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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/powerpc/tm/tm-unavailable.c
Extension
.c
Size
10845 bytes
Lines
412
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 Flags {
	int touch_fp;
	int touch_vec;
	int result;
	int exception;
} flags;

bool expecting_failure(void)
{
	if (flags.touch_fp && flags.exception == FP_UNA_EXCEPTION)
		return false;

	if (flags.touch_vec && flags.exception == VEC_UNA_EXCEPTION)
		return false;

	/*
	 * If both FP and VEC are touched it does not mean that touching VSX
	 * won't raise an exception. However since FP and VEC state are already
	 * correctly loaded, the transaction is not aborted (i.e.
	 * treclaimed/trecheckpointed) and MSR.VSX is just set as 1, so a TM
	 * failure is not expected also in this case.
	 */
	if ((flags.touch_fp && flags.touch_vec) &&
	     flags.exception == VSX_UNA_EXCEPTION)
		return false;

	return true;
}

/* Check if failure occurred whilst in transaction. */
bool is_failure(uint64_t condition_reg)
{
	/*
	 * When failure handling occurs, CR0 is set to 0b1010 (0xa). Otherwise
	 * transaction completes without failure and hence reaches out 'tend.'
	 * that sets CR0 to 0b0100 (0x4).
	 */
	return ((condition_reg >> 28) & 0xa) == 0xa;
}

void *tm_una_ping(void *input)
{

	/*
	 * Expected values for vs0 and vs32 after a TM failure. They must never
	 * change, otherwise they got corrupted.
	 */
	uint64_t high_vs0 = 0x5555555555555555;
	uint64_t low_vs0 = 0xffffffffffffffff;
	uint64_t high_vs32 = 0x5555555555555555;
	uint64_t low_vs32 = 0xffffffffffffffff;

	/* Counter for busy wait */
	uint64_t counter = 0x1ff000000;

	/*
	 * Variable to keep a copy of CR register content taken just after we
	 * leave the transactional state.
	 */
	uint64_t cr_ = 0;

	/*
	 * Wait a bit so thread can get its name "ping". This is not important
	 * to reproduce the issue but it's nice to have for systemtap debugging.
	 */
	if (DEBUG)
		sleep(1);

	printf("If MSR.FP=%d MSR.VEC=%d: ", flags.touch_fp, flags.touch_vec);

	if (flags.exception != FP_UNA_EXCEPTION &&
	    flags.exception != VEC_UNA_EXCEPTION &&
	    flags.exception != VSX_UNA_EXCEPTION) {
		printf("No valid exception specified to test.\n");
		return NULL;
	}

	asm (
		/* Prepare to merge low and high. */
		"	mtvsrd		33, %[high_vs0]		;"
		"	mtvsrd		34, %[low_vs0]		;"

		/*
		 * Adjust VS0 expected value after an TM failure,
		 * i.e. vs0 = 0x5555555555555555555FFFFFFFFFFFFFFFF
		 */
		"	xxmrghd		0, 33, 34		;"

		/*
		 * Adjust VS32 expected value after an TM failure,

Annotation

Implementation Notes