1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
296d01610SSam bobroff /* Test context switching to see if the DSCR SPR is correctly preserved
396d01610SSam bobroff * when within a transaction.
496d01610SSam bobroff *
596d01610SSam bobroff * Note: We assume that the DSCR has been left at the default value (0)
696d01610SSam bobroff * for all CPUs.
796d01610SSam bobroff *
896d01610SSam bobroff * Method:
996d01610SSam bobroff *
1096d01610SSam bobroff * Set a value into the DSCR.
1196d01610SSam bobroff *
1296d01610SSam bobroff * Start a transaction, and suspend it (*).
1396d01610SSam bobroff *
1496d01610SSam bobroff * Hard loop checking to see if the transaction has become doomed.
1596d01610SSam bobroff *
1696d01610SSam bobroff * Now that we *may* have been preempted, record the DSCR and TEXASR SPRS.
1796d01610SSam bobroff *
1896d01610SSam bobroff * If the abort was because of a context switch, check the DSCR value.
1996d01610SSam bobroff * Otherwise, try again.
2096d01610SSam bobroff *
2196d01610SSam bobroff * (*) If the transaction is not suspended we can't see the problem because
2296d01610SSam bobroff * the transaction abort handler will restore the DSCR to it's checkpointed
2396d01610SSam bobroff * value before we regain control.
2496d01610SSam bobroff */
2596d01610SSam bobroff
2696d01610SSam bobroff #include <inttypes.h>
2796d01610SSam bobroff #include <stdio.h>
2896d01610SSam bobroff #include <stdlib.h>
2996d01610SSam bobroff #include <assert.h>
3096d01610SSam bobroff #include <asm/tm.h>
3196d01610SSam bobroff
32aa83f3d8SMichael Ellerman #include "utils.h"
33b319ee84SMichael Ellerman #include "tm.h"
3499597cedSSam Bobroff #include "../pmu/lib.h"
35aa83f3d8SMichael Ellerman
3696d01610SSam bobroff #define SPRN_DSCR 0x03
3796d01610SSam bobroff
test_body(void)38aa83f3d8SMichael Ellerman int test_body(void)
39aa83f3d8SMichael Ellerman {
4096d01610SSam bobroff uint64_t rv, dscr1 = 1, dscr2, texasr;
4196d01610SSam bobroff
42b319ee84SMichael Ellerman SKIP_IF(!have_htm());
43*e42edf9bSJordan Niethe SKIP_IF(htm_is_synthetic());
44b319ee84SMichael Ellerman
4596d01610SSam bobroff printf("Check DSCR TM context switch: ");
4696d01610SSam bobroff fflush(stdout);
4796d01610SSam bobroff for (;;) {
4896d01610SSam bobroff asm __volatile__ (
4996d01610SSam bobroff /* set a known value into the DSCR */
5096d01610SSam bobroff "ld 3, %[dscr1];"
5196d01610SSam bobroff "mtspr %[sprn_dscr], 3;"
5296d01610SSam bobroff
53fe06fe86SMichael Ellerman "li %[rv], 1;"
5496d01610SSam bobroff /* start and suspend a transaction */
55da3ddc3bSRashmica Gupta "tbegin.;"
5696d01610SSam bobroff "beq 1f;"
57da3ddc3bSRashmica Gupta "tsuspend.;"
5896d01610SSam bobroff
5996d01610SSam bobroff /* hard loop until the transaction becomes doomed */
6096d01610SSam bobroff "2: ;"
61da3ddc3bSRashmica Gupta "tcheck 0;"
6296d01610SSam bobroff "bc 4, 0, 2b;"
6396d01610SSam bobroff
6496d01610SSam bobroff /* record DSCR and TEXASR */
6596d01610SSam bobroff "mfspr 3, %[sprn_dscr];"
6696d01610SSam bobroff "std 3, %[dscr2];"
6796d01610SSam bobroff "mfspr 3, %[sprn_texasr];"
6896d01610SSam bobroff "std 3, %[texasr];"
6996d01610SSam bobroff
70da3ddc3bSRashmica Gupta "tresume.;"
71da3ddc3bSRashmica Gupta "tend.;"
7296d01610SSam bobroff "li %[rv], 0;"
7396d01610SSam bobroff "1: ;"
7496d01610SSam bobroff : [rv]"=r"(rv), [dscr2]"=m"(dscr2), [texasr]"=m"(texasr)
7596d01610SSam bobroff : [dscr1]"m"(dscr1)
7696d01610SSam bobroff , [sprn_dscr]"i"(SPRN_DSCR), [sprn_texasr]"i"(SPRN_TEXASR)
7796d01610SSam bobroff : "memory", "r3"
7896d01610SSam bobroff );
7996d01610SSam bobroff assert(rv); /* make sure the transaction aborted */
8096d01610SSam bobroff if ((texasr >> 56) != TM_CAUSE_RESCHED) {
8196d01610SSam bobroff continue;
8296d01610SSam bobroff }
8396d01610SSam bobroff if (dscr2 != dscr1) {
8496d01610SSam bobroff printf(" FAIL\n");
85aa83f3d8SMichael Ellerman return 1;
8696d01610SSam bobroff } else {
8796d01610SSam bobroff printf(" OK\n");
88aa83f3d8SMichael Ellerman return 0;
8996d01610SSam bobroff }
9096d01610SSam bobroff }
9196d01610SSam bobroff }
92aa83f3d8SMichael Ellerman
tm_resched_dscr(void)9399597cedSSam Bobroff static int tm_resched_dscr(void)
94aa83f3d8SMichael Ellerman {
9599597cedSSam Bobroff return eat_cpu(test_body);
9699597cedSSam Bobroff }
9799597cedSSam Bobroff
main(int argc,const char * argv[])9899597cedSSam Bobroff int main(int argc, const char *argv[])
9999597cedSSam Bobroff {
10099597cedSSam Bobroff return test_harness(tm_resched_dscr, "tm_resched_dscr");
101aa83f3d8SMichael Ellerman }
102