cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tm-resched-dscr.c (2256B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Test context switching to see if the DSCR SPR is correctly preserved
      3 * when within a transaction.
      4 *
      5 * Note: We assume that the DSCR has been left at the default value (0)
      6 * for all CPUs.
      7 *
      8 * Method:
      9 *
     10 * Set a value into the DSCR.
     11 *
     12 * Start a transaction, and suspend it (*).
     13 *
     14 * Hard loop checking to see if the transaction has become doomed.
     15 *
     16 * Now that we *may* have been preempted, record the DSCR and TEXASR SPRS.
     17 *
     18 * If the abort was because of a context switch, check the DSCR value.
     19 * Otherwise, try again.
     20 *
     21 * (*) If the transaction is not suspended we can't see the problem because
     22 * the transaction abort handler will restore the DSCR to it's checkpointed
     23 * value before we regain control.
     24 */
     25
     26#include <inttypes.h>
     27#include <stdio.h>
     28#include <stdlib.h>
     29#include <assert.h>
     30#include <asm/tm.h>
     31
     32#include "utils.h"
     33#include "tm.h"
     34#include "../pmu/lib.h"
     35
     36#define SPRN_DSCR       0x03
     37
     38int test_body(void)
     39{
     40	uint64_t rv, dscr1 = 1, dscr2, texasr;
     41
     42	SKIP_IF(!have_htm());
     43	SKIP_IF(htm_is_synthetic());
     44
     45	printf("Check DSCR TM context switch: ");
     46	fflush(stdout);
     47	for (;;) {
     48		asm __volatile__ (
     49			/* set a known value into the DSCR */
     50			"ld      3, %[dscr1];"
     51			"mtspr   %[sprn_dscr], 3;"
     52
     53			"li      %[rv], 1;"
     54			/* start and suspend a transaction */
     55			"tbegin.;"
     56			"beq     1f;"
     57			"tsuspend.;"
     58
     59			/* hard loop until the transaction becomes doomed */
     60			"2: ;"
     61			"tcheck 0;"
     62			"bc      4, 0, 2b;"
     63
     64			/* record DSCR and TEXASR */
     65			"mfspr   3, %[sprn_dscr];"
     66			"std     3, %[dscr2];"
     67			"mfspr   3, %[sprn_texasr];"
     68			"std     3, %[texasr];"
     69
     70			"tresume.;"
     71			"tend.;"
     72			"li      %[rv], 0;"
     73			"1: ;"
     74			: [rv]"=r"(rv), [dscr2]"=m"(dscr2), [texasr]"=m"(texasr)
     75			: [dscr1]"m"(dscr1)
     76			, [sprn_dscr]"i"(SPRN_DSCR), [sprn_texasr]"i"(SPRN_TEXASR)
     77			: "memory", "r3"
     78		);
     79		assert(rv); /* make sure the transaction aborted */
     80		if ((texasr >> 56) != TM_CAUSE_RESCHED) {
     81			continue;
     82		}
     83		if (dscr2 != dscr1) {
     84			printf(" FAIL\n");
     85			return 1;
     86		} else {
     87			printf(" OK\n");
     88			return 0;
     89		}
     90	}
     91}
     92
     93static int tm_resched_dscr(void)
     94{
     95	return eat_cpu(test_body);
     96}
     97
     98int main(int argc, const char *argv[])
     99{
    100	return test_harness(tm_resched_dscr, "tm_resched_dscr");
    101}