0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <stdio.h>
0013 #include <stdlib.h>
0014 #include <unistd.h>
0015 #include <signal.h>
0016 #include <inttypes.h>
0017 #include <wait.h>
0018
0019
0020 #include <sys/prctl.h>
0021 #include <linux/prctl.h>
0022
0023
0024 #ifndef PR_GET_TSC
0025 #define PR_GET_TSC 25
0026 #define PR_SET_TSC 26
0027 # define PR_TSC_ENABLE 1
0028 # define PR_TSC_SIGSEGV 2
0029 #endif
0030
0031 static uint64_t rdtsc(void)
0032 {
0033 uint32_t lo, hi;
0034
0035 __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
0036 return (uint64_t)hi << 32 | lo;
0037 }
0038
0039 static void sigsegv_expect(int sig)
0040 {
0041
0042 }
0043
0044 static void segvtask(void)
0045 {
0046 if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0)
0047 {
0048 perror("prctl");
0049 exit(0);
0050 }
0051 signal(SIGSEGV, sigsegv_expect);
0052 alarm(10);
0053 rdtsc();
0054 fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n");
0055 exit(0);
0056 }
0057
0058
0059 static void sigsegv_fail(int sig)
0060 {
0061 fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n");
0062 exit(0);
0063 }
0064
0065 static void rdtsctask(void)
0066 {
0067 if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0)
0068 {
0069 perror("prctl");
0070 exit(0);
0071 }
0072 signal(SIGSEGV, sigsegv_fail);
0073 alarm(10);
0074 for(;;) rdtsc();
0075 }
0076
0077
0078 int main(void)
0079 {
0080 int n_tasks = 100, i;
0081
0082 fprintf(stderr, "[No further output means we're allright]\n");
0083
0084 for (i=0; i<n_tasks; i++)
0085 if (fork() == 0)
0086 {
0087 if (i & 1)
0088 segvtask();
0089 else
0090 rdtsctask();
0091 }
0092
0093 for (i=0; i<n_tasks; i++)
0094 wait(NULL);
0095
0096 exit(0);
0097 }
0098