]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
96d01610 S |
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 | ||
aa83f3d8 | 32 | #include "utils.h" |
b319ee84 | 33 | #include "tm.h" |
99597ced | 34 | #include "../pmu/lib.h" |
aa83f3d8 | 35 | |
96d01610 S |
36 | #define SPRN_DSCR 0x03 |
37 | ||
aa83f3d8 ME |
38 | int test_body(void) |
39 | { | |
96d01610 S |
40 | uint64_t rv, dscr1 = 1, dscr2, texasr; |
41 | ||
b319ee84 ME |
42 | SKIP_IF(!have_htm()); |
43 | ||
96d01610 S |
44 | printf("Check DSCR TM context switch: "); |
45 | fflush(stdout); | |
46 | for (;;) { | |
96d01610 S |
47 | asm __volatile__ ( |
48 | /* set a known value into the DSCR */ | |
49 | "ld 3, %[dscr1];" | |
50 | "mtspr %[sprn_dscr], 3;" | |
51 | ||
fe06fe86 | 52 | "li %[rv], 1;" |
96d01610 | 53 | /* start and suspend a transaction */ |
da3ddc3b | 54 | "tbegin.;" |
96d01610 | 55 | "beq 1f;" |
da3ddc3b | 56 | "tsuspend.;" |
96d01610 S |
57 | |
58 | /* hard loop until the transaction becomes doomed */ | |
59 | "2: ;" | |
da3ddc3b | 60 | "tcheck 0;" |
96d01610 S |
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 | ||
da3ddc3b RG |
69 | "tresume.;" |
70 | "tend.;" | |
96d01610 S |
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) { | |
96d01610 S |
80 | continue; |
81 | } | |
82 | if (dscr2 != dscr1) { | |
83 | printf(" FAIL\n"); | |
aa83f3d8 | 84 | return 1; |
96d01610 S |
85 | } else { |
86 | printf(" OK\n"); | |
aa83f3d8 | 87 | return 0; |
96d01610 S |
88 | } |
89 | } | |
90 | } | |
aa83f3d8 | 91 | |
99597ced | 92 | static int tm_resched_dscr(void) |
aa83f3d8 | 93 | { |
99597ced SB |
94 | return eat_cpu(test_body); |
95 | } | |
96 | ||
97 | int main(int argc, const char *argv[]) | |
98 | { | |
99 | return test_harness(tm_resched_dscr, "tm_resched_dscr"); | |
aa83f3d8 | 100 | } |