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

clockid.c (2545B)


      1// SPDX-License-Identifier: GPL-2.0
      2
      3#include <subcmd/parse-options.h>
      4#include <stdio.h>
      5#include <time.h>
      6#include <strings.h>
      7#include <linux/time64.h>
      8#include "debug.h"
      9#include "clockid.h"
     10#include "record.h"
     11
     12struct clockid_map {
     13	const char *name;
     14	int clockid;
     15};
     16
     17#define CLOCKID_MAP(n, c)	\
     18	{ .name = n, .clockid = (c), }
     19
     20#define CLOCKID_END	{ .name = NULL, }
     21
     22
     23/*
     24 * Add the missing ones, we need to build on many distros...
     25 */
     26#ifndef CLOCK_MONOTONIC_RAW
     27#define CLOCK_MONOTONIC_RAW 4
     28#endif
     29#ifndef CLOCK_BOOTTIME
     30#define CLOCK_BOOTTIME 7
     31#endif
     32#ifndef CLOCK_TAI
     33#define CLOCK_TAI 11
     34#endif
     35
     36static const struct clockid_map clockids[] = {
     37	/* available for all events, NMI safe */
     38	CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),
     39	CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),
     40
     41	/* available for some events */
     42	CLOCKID_MAP("realtime", CLOCK_REALTIME),
     43	CLOCKID_MAP("boottime", CLOCK_BOOTTIME),
     44	CLOCKID_MAP("tai", CLOCK_TAI),
     45
     46	/* available for the lazy */
     47	CLOCKID_MAP("mono", CLOCK_MONOTONIC),
     48	CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),
     49	CLOCKID_MAP("real", CLOCK_REALTIME),
     50	CLOCKID_MAP("boot", CLOCK_BOOTTIME),
     51
     52	CLOCKID_END,
     53};
     54
     55static int get_clockid_res(clockid_t clk_id, u64 *res_ns)
     56{
     57	struct timespec res;
     58
     59	*res_ns = 0;
     60	if (!clock_getres(clk_id, &res))
     61		*res_ns = res.tv_nsec + res.tv_sec * NSEC_PER_SEC;
     62	else
     63		pr_warning("WARNING: Failed to determine specified clock resolution.\n");
     64
     65	return 0;
     66}
     67
     68int parse_clockid(const struct option *opt, const char *str, int unset)
     69{
     70	struct record_opts *opts = (struct record_opts *)opt->value;
     71	const struct clockid_map *cm;
     72	const char *ostr = str;
     73
     74	if (unset) {
     75		opts->use_clockid = 0;
     76		return 0;
     77	}
     78
     79	/* no arg passed */
     80	if (!str)
     81		return 0;
     82
     83	/* no setting it twice */
     84	if (opts->use_clockid)
     85		return -1;
     86
     87	opts->use_clockid = true;
     88
     89	/* if its a number, we're done */
     90	if (sscanf(str, "%d", &opts->clockid) == 1)
     91		return get_clockid_res(opts->clockid, &opts->clockid_res_ns);
     92
     93	/* allow a "CLOCK_" prefix to the name */
     94	if (!strncasecmp(str, "CLOCK_", 6))
     95		str += 6;
     96
     97	for (cm = clockids; cm->name; cm++) {
     98		if (!strcasecmp(str, cm->name)) {
     99			opts->clockid = cm->clockid;
    100			return get_clockid_res(opts->clockid,
    101					       &opts->clockid_res_ns);
    102		}
    103	}
    104
    105	opts->use_clockid = false;
    106	ui__warning("unknown clockid %s, check man page\n", ostr);
    107	return -1;
    108}
    109
    110const char *clockid_name(clockid_t clk_id)
    111{
    112	const struct clockid_map *cm;
    113
    114	for (cm = clockids; cm->name; cm++) {
    115		if (cm->clockid == clk_id)
    116			return cm->name;
    117	}
    118	return "(not found)";
    119}