linux/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c
<<
>>
Prefs
   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
  44        printf("Check DSCR TM context switch: ");
  45        fflush(stdout);
  46        for (;;) {
  47                asm __volatile__ (
  48                        /* set a known value into the DSCR */
  49                        "ld      3, %[dscr1];"
  50                        "mtspr   %[sprn_dscr], 3;"
  51
  52                        "li      %[rv], 1;"
  53                        /* start and suspend a transaction */
  54                        "tbegin.;"
  55                        "beq     1f;"
  56                        "tsuspend.;"
  57
  58                        /* hard loop until the transaction becomes doomed */
  59                        "2: ;"
  60                        "tcheck 0;"
  61                        "bc      4, 0, 2b;"
  62
  63                        /* record DSCR and TEXASR */
  64                        "mfspr   3, %[sprn_dscr];"
  65                        "std     3, %[dscr2];"
  66                        "mfspr   3, %[sprn_texasr];"
  67                        "std     3, %[texasr];"
  68
  69                        "tresume.;"
  70                        "tend.;"
  71                        "li      %[rv], 0;"
  72                        "1: ;"
  73                        : [rv]"=r"(rv), [dscr2]"=m"(dscr2), [texasr]"=m"(texasr)
  74                        : [dscr1]"m"(dscr1)
  75                        , [sprn_dscr]"i"(SPRN_DSCR), [sprn_texasr]"i"(SPRN_TEXASR)
  76                        : "memory", "r3"
  77                );
  78                assert(rv); /* make sure the transaction aborted */
  79                if ((texasr >> 56) != TM_CAUSE_RESCHED) {
  80                        continue;
  81                }
  82                if (dscr2 != dscr1) {
  83                        printf(" FAIL\n");
  84                        return 1;
  85                } else {
  86                        printf(" OK\n");
  87                        return 0;
  88                }
  89        }
  90}
  91
  92static int tm_resched_dscr(void)
  93{
  94        return eat_cpu(test_body);
  95}
  96
  97int main(int argc, const char *argv[])
  98{
  99        return test_harness(tm_resched_dscr, "tm_resched_dscr");
 100}
 101