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. uint64_t rdtsc() {
  27. uint32_t lo, hi;
  28. /* We cannot use "=A", since this would use %rax on x86_64 */
  29. __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
  30. return (uint64_t)hi << 32 | lo;
  31. }
  32. void sigsegv_cb(int sig)
  33. {
  34. int tsc_val = 0;
  35. printf("[ SIG_SEGV ]\n");
  36. printf("prctl(PR_GET_TSC, &tsc_val); ");
  37. fflush(stdout);
  38. if ( prctl(PR_GET_TSC, &tsc_val) == -1)
  39. perror("prctl");
  40. printf("tsc_val == %s\n", tsc_names[tsc_val]);
  41. printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
  42. fflush(stdout);
  43. if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
  44. perror("prctl");
  45. printf("rdtsc() == ");
  46. }
  47. int main(int argc, char **argv)
  48. {
  49. int tsc_val = 0;
  50. signal(SIGSEGV, sigsegv_cb);
  51. printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
  52. printf("prctl(PR_GET_TSC, &tsc_val); ");
  53. fflush(stdout);
  54. if ( prctl(PR_GET_TSC, &tsc_val) == -1)
  55. perror("prctl");
  56. printf("tsc_val == %s\n", tsc_names[tsc_val]);
  57. printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
  58. printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
  59. fflush(stdout);
  60. if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
  61. perror("prctl");
  62. printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
  63. printf("prctl(PR_SET_TSC, PR_TSC_SIGSEGV)\n");
  64. fflush(stdout);
  65. if ( prctl(PR_SET_TSC, PR_TSC_SIGSEGV) == -1)
  66. perror("prctl");
  67. printf("rdtsc() == ");
  68. fflush(stdout);
  69. printf("%llu\n", (unsigned long long)rdtsc());
  70. fflush(stdout);
  71. exit(EXIT_SUCCESS);
  72. }