tm-resched-dscr.c 2.1 KB

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