tm-resched-dscr.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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. #include <inttypes.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <assert.h>
  29. #include <asm/tm.h>
  30. #include "utils.h"
  31. #include "tm.h"
  32. #include "../pmu/lib.h"
  33. #define SPRN_DSCR 0x03
  34. int test_body(void)
  35. {
  36. uint64_t rv, dscr1 = 1, dscr2, texasr;
  37. SKIP_IF(!have_htm());
  38. SKIP_IF(htm_is_synthetic());
  39. printf("Check DSCR TM context switch: ");
  40. fflush(stdout);
  41. for (;;) {
  42. asm __volatile__ (
  43. /* set a known value into the DSCR */
  44. "ld 3, %[dscr1];"
  45. "mtspr %[sprn_dscr], 3;"
  46. "li %[rv], 1;"
  47. /* start and suspend a transaction */
  48. "tbegin.;"
  49. "beq 1f;"
  50. "tsuspend.;"
  51. /* hard loop until the transaction becomes doomed */
  52. "2: ;"
  53. "tcheck 0;"
  54. "bc 4, 0, 2b;"
  55. /* record DSCR and TEXASR */
  56. "mfspr 3, %[sprn_dscr];"
  57. "std 3, %[dscr2];"
  58. "mfspr 3, %[sprn_texasr];"
  59. "std 3, %[texasr];"
  60. "tresume.;"
  61. "tend.;"
  62. "li %[rv], 0;"
  63. "1: ;"
  64. : [rv]"=r"(rv), [dscr2]"=m"(dscr2), [texasr]"=m"(texasr)
  65. : [dscr1]"m"(dscr1)
  66. , [sprn_dscr]"i"(SPRN_DSCR), [sprn_texasr]"i"(SPRN_TEXASR)
  67. : "memory", "r3"
  68. );
  69. assert(rv); /* make sure the transaction aborted */
  70. if ((texasr >> 56) != TM_CAUSE_RESCHED) {
  71. continue;
  72. }
  73. if (dscr2 != dscr1) {
  74. printf(" FAIL\n");
  75. return 1;
  76. } else {
  77. printf(" OK\n");
  78. return 0;
  79. }
  80. }
  81. }
  82. static int tm_resched_dscr(void)
  83. {
  84. return eat_cpu(test_body);
  85. }
  86. int main(int argc, const char *argv[])
  87. {
  88. return test_harness(tm_resched_dscr, "tm_resched_dscr");
  89. }