disable-tsc-test.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
  3. *
  4. * Basic test to test behaviour of PR_GET_TSC and PR_SET_TSC
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  9. #include <signal.h>
  10. #include <inttypes.h>
  11. #include <sys/prctl.h>
  12. #include <linux/prctl.h>
  13. /* Get/set the process' ability to use the timestamp counter instruction */
  14. #ifndef PR_GET_TSC
  15. #define PR_GET_TSC 25
  16. #define PR_SET_TSC 26
  17. # define PR_TSC_ENABLE 1 /* allow the use of the timestamp counter */
  18. # define PR_TSC_SIGSEGV 2 /* throw a SIGSEGV instead of reading the TSC */
  19. #endif
  20. const char *tsc_names[] =
  21. {
  22. [0] = "[not set]",
  23. [PR_TSC_ENABLE] = "PR_TSC_ENABLE",
  24. [PR_TSC_SIGSEGV] = "PR_TSC_SIGSEGV",
  25. };
  26. static uint64_t rdtsc(void)
  27. {
  28. uint32_t lo, hi;
  29. /* We cannot use "=A", since this would use %rax on x86_64 */
  30. __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
  31. return (uint64_t)hi << 32 | lo;
  32. }
  33. static void sigsegv_cb(int sig)
  34. {
  35. int tsc_val = 0;
  36. printf("[ SIG_SEGV ]\n");
  37. printf("prctl(PR_GET_TSC, &tsc_val); ");
  38. fflush(stdout);
  39. if ( prctl(PR_GET_TSC, &tsc_val) == -1)
  40. perror("prctl");
  41. printf("tsc_val == %s\n", tsc_names[tsc_val]);
  42. printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
  43. fflush(stdout);
  44. if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
  45. perror("prctl");
  46. printf("rdtsc() == ");
  47. }
  48. int main(int argc, char **argv)
  49. {
  50. int tsc_val = 0;
  51. signal(SIGSEGV, sigsegv_cb);
  52. printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
  53. printf("prctl(PR_GET_TSC, &tsc_val); ");
  54. fflush(stdout);
  55. if ( prctl(PR_GET_TSC, &tsc_val) == -1)
  56. perror("prctl");
  57. printf("tsc_val == %s\n", tsc_names[tsc_val]);
  58. printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
  59. printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
  60. fflush(stdout);
  61. if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
  62. perror("prctl");
  63. printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
  64. printf("prctl(PR_SET_TSC, PR_TSC_SIGSEGV)\n");
  65. fflush(stdout);
  66. if ( prctl(PR_SET_TSC, PR_TSC_SIGSEGV) == -1)
  67. perror("prctl");
  68. printf("rdtsc() == ");
  69. fflush(stdout);
  70. printf("%llu\n", (unsigned long long)rdtsc());
  71. fflush(stdout);
  72. exit(EXIT_SUCCESS);
  73. }