tools/testing/selftests/powerpc/tm/tm-trap.c

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/powerpc/tm/tm-trap.c
Extension
.c
Size
9475 bytes
Lines
335
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

if (trap_event == 0) {
			/* Do nothing. Since it is returning from this trap
			 * event that endianness is flipped by the bug, so just
			 * let the process return from the signal handler and
			 * check on the second trap event if endianness is
			 * flipped or not.
			 */
		}
		/* Second trap event */
		else if (trap_event == 1) {
			/*
			 * Since trap was caught in TM on first trap event, if
			 * endianness was still LE (not flipped inadvertently)
			 * after returning from the signal handler instruction
			 * (1) is executed (basically a 'nop'), as it's located
			 * at address of tbegin. +4 (rollback addr). As (1) on
			 * LE endianness does in effect nothing, instruction (2)
			 * is then executed again as 'trap', generating a second
			 * trap event (note that in that case 'trap' is caught
			 * not in transacional mode). On te other hand, if after
			 * the return from the signal handler the endianness in-
			 * advertently flipped, instruction (1) is tread as a
			 * branch instruction, i.e. b .+8, hence instruction (3)
			 * and (4) are executed (tbegin.; trap;) and we get sim-
			 * ilaly on the trap signal handler, but now in TM mode.
			 * Either way, it's now possible to check the MSR LE bit
			 * once in the trap handler to verify if endianness was
			 * flipped or not after the return from the second trap
			 * event. If endianness is flipped, the bug is present.
			 * Finally, getting a trap in TM mode or not is just
			 * worth noting because it affects the math to determine
			 * the offset added to the NIP on return: the NIP for a
			 * trap caught in TM is the rollback address, i.e. the
			 * next instruction after 'tbegin.', whilst the NIP for
			 * a trap caught in non-transactional mode is the very
			 * same address of the 'trap' instruction that generated
			 * the trap event.
			 */

			if (thread_endianness == LE) {
				/* Go to 'success', i.e. instruction (6) */
				ucp->uc_mcontext.gp_regs[PT_NIP] += 16;
			} else {
				/*
				 * Thread endianness is BE, so it flipped
				 * inadvertently. Thus we flip back to LE and
				 * set NIP to go to 'failure', instruction (5).
				 */
				ucp->uc_mcontext.gp_regs[PT_MSR] |= 1UL;
				ucp->uc_mcontext.gp_regs[PT_NIP] += 4;
			}
		}
	}

	/*
	 * Big-Endian Machine
	 */

	else {
		/* First trap event */
		if (trap_event == 0) {
			/*
			 * Force thread endianness to be LE. Instructions (1),
			 * (3), and (4) will be executed, generating a second
			 * trap in TM mode.
			 */
			ucp->uc_mcontext.gp_regs[PT_MSR] |= 1UL;
		}
		/* Second trap event */
		else if (trap_event == 1) {
			/*
			 * Do nothing. If bug is present on return from this
			 * second trap event endianness will flip back "automat-
			 * ically" to BE, otherwise thread endianness will
			 * continue to be LE, just as it was set above.
			 */
		}
		/* A third trap event */
		else {
			/*
			 * Once here it means that after returning from the sec-
			 * ond trap event instruction (4) (trap) was executed
			 * as LE, generating a third trap event. In that case
			 * endianness is still LE as set on return from the
			 * first trap event, hence no bug. Otherwise, bug
			 * flipped back to BE on return from the second trap
			 * event and instruction (4) was executed as 'tdi' (so
			 * basically a 'nop') and branch to 'failure' in
			 * instruction (5) was taken to indicate failure and we
			 * never get here.

Annotation

Implementation Notes