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-gpr.c (3089B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Ptrace test for GPR/FPR registers in TM context
      4 *
      5 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
      6 */
      7#include "ptrace.h"
      8#include "ptrace-gpr.h"
      9#include "tm.h"
     10
     11/* Tracer and Tracee Shared Data */
     12int shm_id;
     13unsigned long *cptr, *pptr;
     14
     15float a = FPR_1;
     16float b = FPR_2;
     17float c = FPR_3;
     18
     19void tm_gpr(void)
     20{
     21	unsigned long gpr_buf[18];
     22	unsigned long result, texasr;
     23	float fpr_buf[32];
     24
     25	printf("Starting the child\n");
     26	cptr = (unsigned long *)shmat(shm_id, NULL, 0);
     27
     28trans:
     29	cptr[1] = 0;
     30	asm __volatile__(
     31		ASM_LOAD_GPR_IMMED(gpr_1)
     32		ASM_LOAD_FPR_SINGLE_PRECISION(flt_1)
     33		"1: ;"
     34		"tbegin.;"
     35		"beq 2f;"
     36		ASM_LOAD_GPR_IMMED(gpr_2)
     37		ASM_LOAD_FPR_SINGLE_PRECISION(flt_2)
     38		"tsuspend.;"
     39		"li 7, 1;"
     40		"stw 7, 0(%[cptr1]);"
     41		"tresume.;"
     42		"b .;"
     43
     44		"tend.;"
     45		"li 0, 0;"
     46		"ori %[res], 0, 0;"
     47		"b 3f;"
     48
     49		/* Transaction abort handler */
     50		"2: ;"
     51		"li 0, 1;"
     52		"ori %[res], 0, 0;"
     53		"mfspr %[texasr], %[sprn_texasr];"
     54
     55		"3: ;"
     56		: [res] "=r" (result), [texasr] "=r" (texasr)
     57		: [gpr_1]"i"(GPR_1), [gpr_2]"i"(GPR_2),
     58		[sprn_texasr] "i" (SPRN_TEXASR), [flt_1] "b" (&a),
     59		[flt_2] "b" (&b), [cptr1] "b" (&cptr[1])
     60		: "memory", "r0", "r7", "r8", "r9", "r10",
     61		"r11", "r12", "r13", "r14", "r15", "r16",
     62		"r17", "r18", "r19", "r20", "r21", "r22",
     63		"r23", "r24", "r25", "r26", "r27", "r28",
     64		"r29", "r30", "r31"
     65		);
     66
     67	if (result) {
     68		if (!cptr[0])
     69			goto trans;
     70
     71		shmdt((void *)cptr);
     72		store_gpr(gpr_buf);
     73		store_fpr_single_precision(fpr_buf);
     74
     75		if (validate_gpr(gpr_buf, GPR_3))
     76			exit(1);
     77
     78		if (validate_fpr_float(fpr_buf, c))
     79			exit(1);
     80
     81		exit(0);
     82	}
     83	shmdt((void *)cptr);
     84	exit(1);
     85}
     86
     87int trace_tm_gpr(pid_t child)
     88{
     89	unsigned long gpr[18];
     90	unsigned long fpr[32];
     91
     92	FAIL_IF(start_trace(child));
     93	FAIL_IF(show_gpr(child, gpr));
     94	FAIL_IF(validate_gpr(gpr, GPR_2));
     95	FAIL_IF(show_fpr(child, fpr));
     96	FAIL_IF(validate_fpr(fpr, FPR_2_REP));
     97	FAIL_IF(show_ckpt_fpr(child, fpr));
     98	FAIL_IF(validate_fpr(fpr, FPR_1_REP));
     99	FAIL_IF(show_ckpt_gpr(child, gpr));
    100	FAIL_IF(validate_gpr(gpr, GPR_1));
    101	FAIL_IF(write_ckpt_gpr(child, GPR_3));
    102	FAIL_IF(write_ckpt_fpr(child, FPR_3_REP));
    103
    104	pptr[0] = 1;
    105	FAIL_IF(stop_trace(child));
    106
    107	return TEST_PASS;
    108}
    109
    110int ptrace_tm_gpr(void)
    111{
    112	pid_t pid;
    113	int ret, status;
    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	pid = fork();
    119	if (pid < 0) {
    120		perror("fork() failed");
    121		return TEST_FAIL;
    122	}
    123	if (pid == 0)
    124		tm_gpr();
    125
    126	if (pid) {
    127		pptr = (unsigned long *)shmat(shm_id, NULL, 0);
    128
    129		while (!pptr[1])
    130			asm volatile("" : : : "memory");
    131		ret = trace_tm_gpr(pid);
    132		if (ret) {
    133			kill(pid, SIGTERM);
    134			return TEST_FAIL;
    135		}
    136
    137		shmdt((void *)pptr);
    138
    139		ret = wait(&status);
    140		shmctl(shm_id, IPC_RMID, NULL);
    141		if (ret != pid) {
    142			printf("Child's exit status not captured\n");
    143			return TEST_FAIL;
    144		}
    145
    146		return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
    147			TEST_PASS;
    148	}
    149	return TEST_PASS;
    150}
    151
    152int main(int argc, char *argv[])
    153{
    154	return test_harness(ptrace_tm_gpr, "ptrace_tm_gpr");
    155}