brintos

brintos / linux-shallow public Read only

0
0
Text · 3.1 KiB · e64cdb0 Raw
165 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Ptrace test TM SPR registers4 *5 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.6 */7#include "ptrace.h"8#include "tm.h"9 10/* Tracee and tracer shared data */11struct shared {12	int flag;13	struct tm_spr_regs regs;14};15unsigned long tfhar;16 17int shm_id;18struct shared *cptr, *pptr;19 20int shm_id1;21int *cptr1, *pptr1;22 23#define TM_KVM_SCHED   0xe0000001ac00000124int validate_tm_spr(struct tm_spr_regs *regs)25{26	FAIL_IF(regs->tm_tfhar != tfhar);27	FAIL_IF((regs->tm_texasr == TM_KVM_SCHED) && (regs->tm_tfiar != 0));28 29	return TEST_PASS;30}31 32void tm_spr(void)33{34	unsigned long result, texasr;35	int ret;36 37	cptr = (struct shared *)shmat(shm_id, NULL, 0);38	cptr1 = (int *)shmat(shm_id1, NULL, 0);39 40trans:41	cptr1[0] = 0;42	asm __volatile__(43		"1: ;"44		/* TM failover handler should follow "tbegin.;" */45		"mflr 31;"46		"bl 4f;"	/* $ = TFHAR - 12 */47		"4: ;"48		"mflr %[tfhar];"49		"mtlr 31;"50 51		"tbegin.;"52		"beq 2f;"53 54		"tsuspend.;"55		"li 8, 1;"56		"sth 8, 0(%[cptr1]);"57		"tresume.;"58		"b .;"59 60		"tend.;"61		"li 0, 0;"62		"ori %[res], 0, 0;"63		"b 3f;"64 65		"2: ;"66 67		"li 0, 1;"68		"ori %[res], 0, 0;"69		"mfspr %[texasr], %[sprn_texasr];"70 71		"3: ;"72		: [tfhar] "=r" (tfhar), [res] "=r" (result),73		[texasr] "=r" (texasr), [cptr1] "=b" (cptr1)74		: [sprn_texasr] "i"  (SPRN_TEXASR)75		: "memory", "r0", "r8", "r31"76		);77 78	/* There are 2 32bit instructions before tbegin. */79	tfhar += 12;80 81	if (result) {82		if (!cptr->flag)83			goto trans;84 85		ret = validate_tm_spr((struct tm_spr_regs *)&cptr->regs);86		shmdt((void *)cptr);87		shmdt((void *)cptr1);88		if (ret)89			exit(1);90		exit(0);91	}92	shmdt((void *)cptr);93	shmdt((void *)cptr1);94	exit(1);95}96 97int trace_tm_spr(pid_t child)98{99	FAIL_IF(start_trace(child));100	FAIL_IF(show_tm_spr(child, (struct tm_spr_regs *)&pptr->regs));101 102	printf("TFHAR: %lx TEXASR: %lx TFIAR: %lx\n", pptr->regs.tm_tfhar,103				pptr->regs.tm_texasr, pptr->regs.tm_tfiar);104 105	pptr->flag = 1;106	FAIL_IF(stop_trace(child));107 108	return TEST_PASS;109}110 111int ptrace_tm_spr(void)112{113	pid_t pid;114	int ret, status;115 116	SKIP_IF_MSG(!have_htm(), "Don't have transactional memory");117	SKIP_IF_MSG(htm_is_synthetic(), "Transactional memory is synthetic");118	shm_id = shmget(IPC_PRIVATE, sizeof(struct shared), 0777|IPC_CREAT);119	shm_id1 = shmget(IPC_PRIVATE, sizeof(int), 0777|IPC_CREAT);120	pid = fork();121	if (pid < 0) {122		perror("fork() failed");123		return TEST_FAIL;124	}125 126	if (pid == 0)127		tm_spr();128 129	if (pid) {130		pptr = (struct shared *)shmat(shm_id, NULL, 0);131		pptr1 = (int *)shmat(shm_id1, NULL, 0);132 133		while (!pptr1[0])134			asm volatile("" : : : "memory");135		ret = trace_tm_spr(pid);136		if (ret) {137			kill(pid, SIGKILL);138			shmdt((void *)pptr);139			shmdt((void *)pptr1);140			shmctl(shm_id, IPC_RMID, NULL);141			shmctl(shm_id1, IPC_RMID, NULL);142			return TEST_FAIL;143		}144 145		shmdt((void *)pptr);146		shmdt((void *)pptr1);147		ret = wait(&status);148		shmctl(shm_id, IPC_RMID, NULL);149		shmctl(shm_id1, 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_spr, "ptrace_tm_spr");164}165