cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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