root/tools/testing/selftests/prctl/disable-tsc-test.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rdtsc
  2. sigsegv_cb
  3. main

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

/* [<][>][^][v][top][bottom][index][help] */