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

event.c (3223B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright 2013, Michael Ellerman, IBM Corp.
      4 */
      5
      6#define _GNU_SOURCE
      7#include <unistd.h>
      8#include <sys/syscall.h>
      9#include <string.h>
     10#include <stdio.h>
     11#include <stdbool.h>
     12#include <sys/ioctl.h>
     13
     14#include "event.h"
     15
     16
     17int perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu,
     18		int group_fd, unsigned long flags)
     19{
     20	return syscall(__NR_perf_event_open, attr, pid, cpu,
     21			   group_fd, flags);
     22}
     23
     24static void  __event_init_opts(struct event *e, u64 config,
     25			       int type, char *name, bool sampling)
     26{
     27	memset(e, 0, sizeof(*e));
     28
     29	e->name = name;
     30
     31	e->attr.type = type;
     32	e->attr.config = config;
     33	e->attr.size = sizeof(e->attr);
     34	/* This has to match the structure layout in the header */
     35	e->attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | \
     36				  PERF_FORMAT_TOTAL_TIME_RUNNING;
     37	if (sampling) {
     38		e->attr.sample_period = 1000;
     39		e->attr.sample_type = PERF_SAMPLE_REGS_INTR;
     40		e->attr.disabled = 1;
     41	}
     42}
     43
     44void event_init_opts(struct event *e, u64 config, int type, char *name)
     45{
     46	__event_init_opts(e, config, type, name, false);
     47}
     48
     49void event_init_named(struct event *e, u64 config, char *name)
     50{
     51	event_init_opts(e, config, PERF_TYPE_RAW, name);
     52}
     53
     54void event_init(struct event *e, u64 config)
     55{
     56	event_init_opts(e, config, PERF_TYPE_RAW, "event");
     57}
     58
     59void event_init_sampling(struct event *e, u64 config)
     60{
     61	__event_init_opts(e, config, PERF_TYPE_RAW, "event", true);
     62}
     63
     64#define PERF_CURRENT_PID	0
     65#define PERF_NO_PID		-1
     66#define PERF_NO_CPU		-1
     67#define PERF_NO_GROUP		-1
     68
     69int event_open_with_options(struct event *e, pid_t pid, int cpu, int group_fd)
     70{
     71	e->fd = perf_event_open(&e->attr, pid, cpu, group_fd, 0);
     72	if (e->fd == -1) {
     73		perror("perf_event_open");
     74		return -1;
     75	}
     76
     77	return 0;
     78}
     79
     80int event_open_with_group(struct event *e, int group_fd)
     81{
     82	return event_open_with_options(e, PERF_CURRENT_PID, PERF_NO_CPU, group_fd);
     83}
     84
     85int event_open_with_pid(struct event *e, pid_t pid)
     86{
     87	return event_open_with_options(e, pid, PERF_NO_CPU, PERF_NO_GROUP);
     88}
     89
     90int event_open_with_cpu(struct event *e, int cpu)
     91{
     92	return event_open_with_options(e, PERF_NO_PID, cpu, PERF_NO_GROUP);
     93}
     94
     95int event_open(struct event *e)
     96{
     97	return event_open_with_options(e, PERF_CURRENT_PID, PERF_NO_CPU, PERF_NO_GROUP);
     98}
     99
    100void event_close(struct event *e)
    101{
    102	close(e->fd);
    103}
    104
    105int event_enable(struct event *e)
    106{
    107	return ioctl(e->fd, PERF_EVENT_IOC_ENABLE);
    108}
    109
    110int event_disable(struct event *e)
    111{
    112	return ioctl(e->fd, PERF_EVENT_IOC_DISABLE);
    113}
    114
    115int event_reset(struct event *e)
    116{
    117	return ioctl(e->fd, PERF_EVENT_IOC_RESET);
    118}
    119
    120int event_read(struct event *e)
    121{
    122	int rc;
    123
    124	rc = read(e->fd, &e->result, sizeof(e->result));
    125	if (rc != sizeof(e->result)) {
    126		fprintf(stderr, "read error on event %p!\n", e);
    127		return -1;
    128	}
    129
    130	return 0;
    131}
    132
    133void event_report_justified(struct event *e, int name_width, int result_width)
    134{
    135	printf("%*s: result %*llu ", name_width, e->name, result_width,
    136	       e->result.value);
    137
    138	if (e->result.running == e->result.enabled)
    139		printf("running/enabled %llu\n", e->result.running);
    140	else
    141		printf("running %llu enabled %llu\n", e->result.running,
    142			e->result.enabled);
    143}
    144
    145void event_report(struct event *e)
    146{
    147	event_report_justified(e, 0, 0);
    148}