tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c
Extension
.c
Size
3217 bytes
Lines
165
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct shared {
	int flag;
	struct tm_spr_regs regs;
};
unsigned long tfhar;

int shm_id;
struct shared *cptr, *pptr;

int shm_id1;
int *cptr1, *pptr1;

#define TM_KVM_SCHED   0xe0000001ac000001
int validate_tm_spr(struct tm_spr_regs *regs)
{
	FAIL_IF(regs->tm_tfhar != tfhar);
	FAIL_IF((regs->tm_texasr == TM_KVM_SCHED) && (regs->tm_tfiar != 0));

	return TEST_PASS;
}

void tm_spr(void)
{
	unsigned long result, texasr;
	int ret;

	cptr = (struct shared *)shmat(shm_id, NULL, 0);
	cptr1 = (int *)shmat(shm_id1, NULL, 0);

trans:
	cptr1[0] = 0;
	asm __volatile__(
		"1: ;"
		/* TM failover handler should follow "tbegin.;" */
		"mflr 31;"
		"bl 4f;"	/* $ = TFHAR - 12 */
		"4: ;"
		"mflr %[tfhar];"
		"mtlr 31;"

		"tbegin.;"
		"beq 2f;"

		"tsuspend.;"
		"li 8, 1;"
		"sth 8, 0(%[cptr1]);"
		"tresume.;"
		"b .;"

		"tend.;"
		"li 0, 0;"
		"ori %[res], 0, 0;"
		"b 3f;"

		"2: ;"

		"li 0, 1;"
		"ori %[res], 0, 0;"
		"mfspr %[texasr], %[sprn_texasr];"

		"3: ;"
		: [tfhar] "=r" (tfhar), [res] "=r" (result),
		[texasr] "=r" (texasr), [cptr1] "=b" (cptr1)
		: [sprn_texasr] "i"  (SPRN_TEXASR)
		: "memory", "r0", "r8", "r31"
		);

	/* There are 2 32bit instructions before tbegin. */
	tfhar += 12;

	if (result) {
		if (!cptr->flag)
			goto trans;

		ret = validate_tm_spr((struct tm_spr_regs *)&cptr->regs);
		shmdt((void *)cptr);
		shmdt((void *)cptr1);
		if (ret)
			exit(1);
		exit(0);
	}
	shmdt((void *)cptr);
	shmdt((void *)cptr1);
	exit(1);
}

int trace_tm_spr(pid_t child)
{
	FAIL_IF(start_trace(child));
	FAIL_IF(show_tm_spr(child, (struct tm_spr_regs *)&pptr->regs));

Annotation

Implementation Notes