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