disable-tsc-test.c (2158B)
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 26const char *tsc_names[] = 27{ 28 [0] = "[not set]", 29 [PR_TSC_ENABLE] = "PR_TSC_ENABLE", 30 [PR_TSC_SIGSEGV] = "PR_TSC_SIGSEGV", 31}; 32 33static uint64_t rdtsc(void) 34{ 35uint32_t lo, hi; 36/* We cannot use "=A", since this would use %rax on x86_64 */ 37__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); 38return (uint64_t)hi << 32 | lo; 39} 40 41static 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 61int 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