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

timer.c (2689B)


      1// SPDX-License-Identifier: GPL-2.0
      2#define _GNU_SOURCE
      3#include <sched.h>
      4
      5#include <sys/syscall.h>
      6#include <sys/types.h>
      7#include <sys/wait.h>
      8#include <time.h>
      9#include <unistd.h>
     10#include <stdlib.h>
     11#include <stdio.h>
     12#include <stdint.h>
     13#include <signal.h>
     14
     15#include "log.h"
     16#include "timens.h"
     17
     18int run_test(int clockid, struct timespec now)
     19{
     20	struct itimerspec new_value;
     21	long long elapsed;
     22	timer_t fd;
     23	int i;
     24
     25	if (check_skip(clockid))
     26		return 0;
     27
     28	for (i = 0; i < 2; i++) {
     29		struct sigevent sevp = {.sigev_notify = SIGEV_NONE};
     30		int flags = 0;
     31
     32		new_value.it_value.tv_sec = 3600;
     33		new_value.it_value.tv_nsec = 0;
     34		new_value.it_interval.tv_sec = 1;
     35		new_value.it_interval.tv_nsec = 0;
     36
     37		if (i == 1) {
     38			new_value.it_value.tv_sec += now.tv_sec;
     39			new_value.it_value.tv_nsec += now.tv_nsec;
     40		}
     41
     42		if (timer_create(clockid, &sevp, &fd) == -1) {
     43			if (errno == ENOSYS) {
     44				ksft_test_result_skip("Posix Clocks & timers are supported\n");
     45				return 0;
     46			}
     47			return pr_perror("timerfd_create");
     48		}
     49
     50		if (i == 1)
     51			flags |= TIMER_ABSTIME;
     52		if (timer_settime(fd, flags, &new_value, NULL) == -1)
     53			return pr_perror("timerfd_settime");
     54
     55		if (timer_gettime(fd, &new_value) == -1)
     56			return pr_perror("timerfd_gettime");
     57
     58		elapsed = new_value.it_value.tv_sec;
     59		if (abs(elapsed - 3600) > 60) {
     60			ksft_test_result_fail("clockid: %d elapsed: %lld\n",
     61					      clockid, elapsed);
     62			return 1;
     63		}
     64	}
     65
     66	ksft_test_result_pass("clockid=%d\n", clockid);
     67
     68	return 0;
     69}
     70
     71int main(int argc, char *argv[])
     72{
     73	int ret, status, len, fd;
     74	char buf[4096];
     75	pid_t pid;
     76	struct timespec btime_now, mtime_now;
     77
     78	nscheck();
     79
     80	check_supported_timers();
     81
     82	ksft_set_plan(3);
     83
     84	clock_gettime(CLOCK_MONOTONIC, &mtime_now);
     85	clock_gettime(CLOCK_BOOTTIME, &btime_now);
     86
     87	if (unshare_timens())
     88		return 1;
     89
     90	len = snprintf(buf, sizeof(buf), "%d %d 0\n%d %d 0",
     91			CLOCK_MONOTONIC, 70 * 24 * 3600,
     92			CLOCK_BOOTTIME, 9 * 24 * 3600);
     93	fd = open("/proc/self/timens_offsets", O_WRONLY);
     94	if (fd < 0)
     95		return pr_perror("/proc/self/timens_offsets");
     96
     97	if (write(fd, buf, len) != len)
     98		return pr_perror("/proc/self/timens_offsets");
     99
    100	close(fd);
    101	mtime_now.tv_sec += 70 * 24 * 3600;
    102	btime_now.tv_sec += 9 * 24 * 3600;
    103
    104	pid = fork();
    105	if (pid < 0)
    106		return pr_perror("Unable to fork");
    107	if (pid == 0) {
    108		ret = 0;
    109		ret |= run_test(CLOCK_BOOTTIME, btime_now);
    110		ret |= run_test(CLOCK_MONOTONIC, mtime_now);
    111		ret |= run_test(CLOCK_BOOTTIME_ALARM, btime_now);
    112
    113		if (ret)
    114			ksft_exit_fail();
    115		ksft_exit_pass();
    116		return ret;
    117	}
    118
    119	if (waitpid(pid, &status, 0) != pid)
    120		return pr_perror("Unable to wait the child process");
    121
    122	if (WIFEXITED(status))
    123		return WEXITSTATUS(status);
    124
    125	return 1;
    126}