File Index
Files and directories
Sign in
FILE

ptrace-tm-spr.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Ptrace test TM SPR registers
  4 *
  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   0xe0000001ac000001
 24int 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}
~/ Read-only file preview.