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

hpet_example.c (5591B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <stdio.h>
      3#include <stdlib.h>
      4#include <unistd.h>
      5#include <fcntl.h>
      6#include <string.h>
      7#include <memory.h>
      8#include <malloc.h>
      9#include <time.h>
     10#include <ctype.h>
     11#include <sys/types.h>
     12#include <sys/wait.h>
     13#include <signal.h>
     14#include <errno.h>
     15#include <sys/time.h>
     16#include <linux/hpet.h>
     17
     18
     19extern void hpet_open_close(int, const char **);
     20extern void hpet_info(int, const char **);
     21extern void hpet_poll(int, const char **);
     22extern void hpet_fasync(int, const char **);
     23extern void hpet_read(int, const char **);
     24
     25#include <sys/poll.h>
     26#include <sys/ioctl.h>
     27
     28struct hpet_command {
     29	char		*command;
     30	void		(*func)(int argc, const char ** argv);
     31} hpet_command[] = {
     32	{
     33		"open-close",
     34		hpet_open_close
     35	},
     36	{
     37		"info",
     38		hpet_info
     39	},
     40	{
     41		"poll",
     42		hpet_poll
     43	},
     44	{
     45		"fasync",
     46		hpet_fasync
     47	},
     48};
     49
     50int
     51main(int argc, const char ** argv)
     52{
     53	unsigned int	i;
     54
     55	argc--;
     56	argv++;
     57
     58	if (!argc) {
     59		fprintf(stderr, "-hpet: requires command\n");
     60		return -1;
     61	}
     62
     63
     64	for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
     65		if (!strcmp(argv[0], hpet_command[i].command)) {
     66			argc--;
     67			argv++;
     68			fprintf(stderr, "-hpet: executing %s\n",
     69				hpet_command[i].command);
     70			hpet_command[i].func(argc, argv);
     71			return 0;
     72		}
     73
     74	fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);
     75
     76	return -1;
     77}
     78
     79void
     80hpet_open_close(int argc, const char **argv)
     81{
     82	int	fd;
     83
     84	if (argc != 1) {
     85		fprintf(stderr, "hpet_open_close: device-name\n");
     86		return;
     87	}
     88
     89	fd = open(argv[0], O_RDONLY);
     90	if (fd < 0)
     91		fprintf(stderr, "hpet_open_close: open failed\n");
     92	else
     93		close(fd);
     94
     95	return;
     96}
     97
     98void
     99hpet_info(int argc, const char **argv)
    100{
    101	struct hpet_info	info;
    102	int			fd;
    103
    104	if (argc != 1) {
    105		fprintf(stderr, "hpet_info: device-name\n");
    106		return;
    107	}
    108
    109	fd = open(argv[0], O_RDONLY);
    110	if (fd < 0) {
    111		fprintf(stderr, "hpet_info: open of %s failed\n", argv[0]);
    112		return;
    113	}
    114
    115	if (ioctl(fd, HPET_INFO, &info) < 0) {
    116		fprintf(stderr, "hpet_info: failed to get info\n");
    117		goto out;
    118	}
    119
    120	fprintf(stderr, "hpet_info: hi_irqfreq 0x%lx hi_flags 0x%lx ",
    121		info.hi_ireqfreq, info.hi_flags);
    122	fprintf(stderr, "hi_hpet %d hi_timer %d\n",
    123		info.hi_hpet, info.hi_timer);
    124
    125out:
    126	close(fd);
    127	return;
    128}
    129
    130void
    131hpet_poll(int argc, const char **argv)
    132{
    133	unsigned long		freq;
    134	int			iterations, i, fd;
    135	struct pollfd		pfd;
    136	struct hpet_info	info;
    137	struct timeval		stv, etv;
    138	struct timezone		tz;
    139	long			usec;
    140
    141	if (argc != 3) {
    142		fprintf(stderr, "hpet_poll: device-name freq iterations\n");
    143		return;
    144	}
    145
    146	freq = atoi(argv[1]);
    147	iterations = atoi(argv[2]);
    148
    149	fd = open(argv[0], O_RDONLY);
    150
    151	if (fd < 0) {
    152		fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
    153		return;
    154	}
    155
    156	if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
    157		fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
    158		goto out;
    159	}
    160
    161	if (ioctl(fd, HPET_INFO, &info) < 0) {
    162		fprintf(stderr, "hpet_poll: failed to get info\n");
    163		goto out;
    164	}
    165
    166	fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);
    167
    168	if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
    169		fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
    170		goto out;
    171	}
    172
    173	if (ioctl(fd, HPET_IE_ON, 0) < 0) {
    174		fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
    175		goto out;
    176	}
    177
    178	pfd.fd = fd;
    179	pfd.events = POLLIN;
    180
    181	for (i = 0; i < iterations; i++) {
    182		pfd.revents = 0;
    183		gettimeofday(&stv, &tz);
    184		if (poll(&pfd, 1, -1) < 0)
    185			fprintf(stderr, "hpet_poll: poll failed\n");
    186		else {
    187			long 	data;
    188
    189			gettimeofday(&etv, &tz);
    190			usec = stv.tv_sec * 1000000 + stv.tv_usec;
    191			usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;
    192
    193			fprintf(stderr,
    194				"hpet_poll: expired time = 0x%lx\n", usec);
    195
    196			fprintf(stderr, "hpet_poll: revents = 0x%x\n",
    197				pfd.revents);
    198
    199			if (read(fd, &data, sizeof(data)) != sizeof(data)) {
    200				fprintf(stderr, "hpet_poll: read failed\n");
    201			}
    202			else
    203				fprintf(stderr, "hpet_poll: data 0x%lx\n",
    204					data);
    205		}
    206	}
    207
    208out:
    209	close(fd);
    210	return;
    211}
    212
    213static int hpet_sigio_count;
    214
    215static void
    216hpet_sigio(int val)
    217{
    218	fprintf(stderr, "hpet_sigio: called\n");
    219	hpet_sigio_count++;
    220}
    221
    222void
    223hpet_fasync(int argc, const char **argv)
    224{
    225	unsigned long		freq;
    226	int			iterations, i, fd, value;
    227	sig_t			oldsig;
    228	struct hpet_info	info;
    229
    230	hpet_sigio_count = 0;
    231	fd = -1;
    232
    233	if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
    234		fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
    235		return;
    236	}
    237
    238	if (argc != 3) {
    239		fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
    240		goto out;
    241	}
    242
    243	fd = open(argv[0], O_RDONLY);
    244
    245	if (fd < 0) {
    246		fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
    247		return;
    248	}
    249
    250
    251	if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
    252		((value = fcntl(fd, F_GETFL)) == 1) ||
    253		(fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
    254		fprintf(stderr, "hpet_fasync: fcntl failed\n");
    255		goto out;
    256	}
    257
    258	freq = atoi(argv[1]);
    259	iterations = atoi(argv[2]);
    260
    261	if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
    262		fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
    263		goto out;
    264	}
    265
    266	if (ioctl(fd, HPET_INFO, &info) < 0) {
    267		fprintf(stderr, "hpet_fasync: failed to get info\n");
    268		goto out;
    269	}
    270
    271	fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);
    272
    273	if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
    274		fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
    275		goto out;
    276	}
    277
    278	if (ioctl(fd, HPET_IE_ON, 0) < 0) {
    279		fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
    280		goto out;
    281	}
    282
    283	for (i = 0; i < iterations; i++) {
    284		(void) pause();
    285		fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
    286	}
    287
    288out:
    289	signal(SIGIO, oldsig);
    290
    291	if (fd >= 0)
    292		close(fd);
    293
    294	return;
    295}