Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
0004  *
0005  * Basic test to test behaviour of PR_GET_TSC and PR_SET_TSC
0006  */
0007 
0008 #include <stdio.h>
0009 #include <stdlib.h>
0010 #include <unistd.h>
0011 #include <signal.h>
0012 #include <inttypes.h>
0013 
0014 
0015 #include <sys/prctl.h>
0016 #include <linux/prctl.h>
0017 
0018 /* Get/set the process' ability to use the timestamp counter instruction */
0019 #ifndef PR_GET_TSC
0020 #define PR_GET_TSC 25
0021 #define PR_SET_TSC 26
0022 # define PR_TSC_ENABLE      1   /* allow the use of the timestamp counter */
0023 # define PR_TSC_SIGSEGV     2   /* throw a SIGSEGV instead of reading the TSC */
0024 #endif
0025 
0026 const char *tsc_names[] =
0027 {
0028     [0] = "[not set]",
0029     [PR_TSC_ENABLE] = "PR_TSC_ENABLE",
0030     [PR_TSC_SIGSEGV] = "PR_TSC_SIGSEGV",
0031 };
0032 
0033 static uint64_t rdtsc(void)
0034 {
0035 uint32_t lo, hi;
0036 /* We cannot use "=A", since this would use %rax on x86_64 */
0037 __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
0038 return (uint64_t)hi << 32 | lo;
0039 }
0040 
0041 static void sigsegv_cb(int sig)
0042 {
0043     int tsc_val = 0;
0044 
0045     printf("[ SIG_SEGV ]\n");
0046     printf("prctl(PR_GET_TSC, &tsc_val); ");
0047     fflush(stdout);
0048 
0049     if ( prctl(PR_GET_TSC, &tsc_val) == -1)
0050         perror("prctl");
0051 
0052     printf("tsc_val == %s\n", tsc_names[tsc_val]);
0053     printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
0054     fflush(stdout);
0055     if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
0056         perror("prctl");
0057 
0058     printf("rdtsc() == ");
0059 }
0060 
0061 int main(void)
0062 {
0063     int tsc_val = 0;
0064 
0065     signal(SIGSEGV, sigsegv_cb);
0066 
0067     printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
0068     printf("prctl(PR_GET_TSC, &tsc_val); ");
0069     fflush(stdout);
0070 
0071     if ( prctl(PR_GET_TSC, &tsc_val) == -1)
0072         perror("prctl");
0073 
0074     printf("tsc_val == %s\n", tsc_names[tsc_val]);
0075     printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
0076     printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
0077     fflush(stdout);
0078 
0079     if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
0080         perror("prctl");
0081 
0082     printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
0083     printf("prctl(PR_SET_TSC, PR_TSC_SIGSEGV)\n");
0084     fflush(stdout);
0085 
0086     if ( prctl(PR_SET_TSC, PR_TSC_SIGSEGV) == -1)
0087         perror("prctl");
0088 
0089     printf("rdtsc() == ");
0090     fflush(stdout);
0091     printf("%llu\n", (unsigned long long)rdtsc());
0092     fflush(stdout);
0093 
0094     exit(EXIT_SUCCESS);
0095 }
0096