cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ptrace-tm-vsx.c (3156B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Ptrace test for VMX/VSX registers in the TM context
      4 *
      5 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
      6 */
      7#include "ptrace.h"
      8#include "tm.h"
      9#include "ptrace-vsx.h"
     10
     11int shm_id;
     12unsigned long *cptr, *pptr;
     13
     14unsigned long fp_load[VEC_MAX];
     15unsigned long fp_store[VEC_MAX];
     16unsigned long fp_load_ckpt[VEC_MAX];
     17unsigned long fp_load_ckpt_new[VEC_MAX];
     18
     19__attribute__((used)) void load_vsx(void)
     20{
     21	loadvsx(fp_load, 0);
     22}
     23
     24__attribute__((used)) void load_vsx_ckpt(void)
     25{
     26	loadvsx(fp_load_ckpt, 0);
     27}
     28
     29void tm_vsx(void)
     30{
     31	unsigned long result, texasr;
     32	int ret;
     33
     34	cptr = (unsigned long *)shmat(shm_id, NULL, 0);
     35
     36trans:
     37	cptr[1] = 0;
     38	asm __volatile__(
     39		"bl load_vsx_ckpt;"
     40
     41		"1: ;"
     42		"tbegin.;"
     43		"beq 2f;"
     44
     45		"bl load_vsx;"
     46		"tsuspend.;"
     47		"li 7, 1;"
     48		"stw 7, 0(%[cptr1]);"
     49		"tresume.;"
     50		"b .;"
     51
     52		"tend.;"
     53		"li 0, 0;"
     54		"ori %[res], 0, 0;"
     55		"b 3f;"
     56
     57		"2: ;"
     58		"li 0, 1;"
     59		"ori %[res], 0, 0;"
     60		"mfspr %[texasr], %[sprn_texasr];"
     61
     62		"3: ;"
     63		: [res] "=r" (result), [texasr] "=r" (texasr)
     64		: [sprn_texasr] "i"  (SPRN_TEXASR), [cptr1] "b" (&cptr[1])
     65		: "memory", "r0", "r3", "r4",
     66		  "r7", "r8", "r9", "r10", "r11", "lr"
     67		);
     68
     69	if (result) {
     70		if (!cptr[0])
     71			goto trans;
     72
     73		shmdt((void *)cptr);
     74		storevsx(fp_store, 0);
     75		ret = compare_vsx_vmx(fp_store, fp_load_ckpt_new);
     76		if (ret)
     77			exit(1);
     78		exit(0);
     79	}
     80	shmdt((void *)cptr);
     81	exit(1);
     82}
     83
     84int trace_tm_vsx(pid_t child)
     85{
     86	unsigned long vsx[VSX_MAX];
     87	unsigned long vmx[VMX_MAX + 2][2];
     88
     89	FAIL_IF(start_trace(child));
     90	FAIL_IF(show_vsx(child, vsx));
     91	FAIL_IF(validate_vsx(vsx, fp_load));
     92	FAIL_IF(show_vmx(child, vmx));
     93	FAIL_IF(validate_vmx(vmx, fp_load));
     94	FAIL_IF(show_vsx_ckpt(child, vsx));
     95	FAIL_IF(validate_vsx(vsx, fp_load_ckpt));
     96	FAIL_IF(show_vmx_ckpt(child, vmx));
     97	FAIL_IF(validate_vmx(vmx, fp_load_ckpt));
     98	memset(vsx, 0, sizeof(vsx));
     99	memset(vmx, 0, sizeof(vmx));
    100
    101	load_vsx_vmx(fp_load_ckpt_new, vsx, vmx);
    102
    103	FAIL_IF(write_vsx_ckpt(child, vsx));
    104	FAIL_IF(write_vmx_ckpt(child, vmx));
    105	pptr[0] = 1;
    106	FAIL_IF(stop_trace(child));
    107	return TEST_PASS;
    108}
    109
    110int ptrace_tm_vsx(void)
    111{
    112	pid_t pid;
    113	int ret, status, i;
    114
    115	SKIP_IF(!have_htm());
    116	SKIP_IF(htm_is_synthetic());
    117	shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
    118
    119	for (i = 0; i < 128; i++) {
    120		fp_load[i] = 1 + rand();
    121		fp_load_ckpt[i] = 1 + 2 * rand();
    122		fp_load_ckpt_new[i] = 1 + 3 * rand();
    123	}
    124
    125	pid = fork();
    126	if (pid < 0) {
    127		perror("fork() failed");
    128		return TEST_FAIL;
    129	}
    130
    131	if (pid == 0)
    132		tm_vsx();
    133
    134	if (pid) {
    135		pptr = (unsigned long *)shmat(shm_id, NULL, 0);
    136		while (!pptr[1])
    137			asm volatile("" : : : "memory");
    138
    139		ret = trace_tm_vsx(pid);
    140		if (ret) {
    141			kill(pid, SIGKILL);
    142			shmdt((void *)pptr);
    143			shmctl(shm_id, IPC_RMID, NULL);
    144			return TEST_FAIL;
    145		}
    146
    147		shmdt((void *)pptr);
    148		ret = wait(&status);
    149		shmctl(shm_id, IPC_RMID, NULL);
    150		if (ret != pid) {
    151			printf("Child's exit status not captured\n");
    152			return TEST_FAIL;
    153		}
    154
    155		return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
    156			TEST_PASS;
    157	}
    158	return TEST_PASS;
    159}
    160
    161int main(int argc, char *argv[])
    162{
    163	return test_harness(ptrace_tm_vsx, "ptrace_tm_vsx");
    164}