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

per_event_excludes.c (2603B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright 2014, Michael Ellerman, IBM Corp.
      4 */
      5
      6#define _GNU_SOURCE
      7
      8#include <elf.h>
      9#include <limits.h>
     10#include <stdio.h>
     11#include <stdbool.h>
     12#include <string.h>
     13#include <sys/prctl.h>
     14
     15#include "event.h"
     16#include "lib.h"
     17#include "utils.h"
     18
     19/*
     20 * Test that per-event excludes work.
     21 */
     22
     23static int per_event_excludes(void)
     24{
     25	struct event *e, events[4];
     26	int i;
     27
     28	SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_2_07));
     29
     30	/*
     31	 * We need to create the events disabled, otherwise the running/enabled
     32	 * counts don't match up.
     33	 */
     34	e = &events[0];
     35	event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
     36			PERF_TYPE_HARDWARE, "instructions");
     37	e->attr.disabled = 1;
     38
     39	e = &events[1];
     40	event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
     41			PERF_TYPE_HARDWARE, "instructions(k)");
     42	e->attr.disabled = 1;
     43	e->attr.exclude_user = 1;
     44	e->attr.exclude_hv = 1;
     45
     46	e = &events[2];
     47	event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
     48			PERF_TYPE_HARDWARE, "instructions(h)");
     49	e->attr.disabled = 1;
     50	e->attr.exclude_user = 1;
     51	e->attr.exclude_kernel = 1;
     52
     53	e = &events[3];
     54	event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
     55			PERF_TYPE_HARDWARE, "instructions(u)");
     56	e->attr.disabled = 1;
     57	e->attr.exclude_hv = 1;
     58	e->attr.exclude_kernel = 1;
     59
     60	FAIL_IF(event_open(&events[0]));
     61
     62	/*
     63	 * The open here will fail if we don't have per event exclude support,
     64	 * because the second event has an incompatible set of exclude settings
     65	 * and we're asking for the events to be in a group.
     66	 */
     67	for (i = 1; i < 4; i++)
     68		FAIL_IF(event_open_with_group(&events[i], events[0].fd));
     69
     70	/*
     71	 * Even though the above will fail without per-event excludes we keep
     72	 * testing in order to be thorough.
     73	 */
     74	prctl(PR_TASK_PERF_EVENTS_ENABLE);
     75
     76	/* Spin for a while */
     77	for (i = 0; i < INT_MAX; i++)
     78		asm volatile("" : : : "memory");
     79
     80	prctl(PR_TASK_PERF_EVENTS_DISABLE);
     81
     82	for (i = 0; i < 4; i++) {
     83		FAIL_IF(event_read(&events[i]));
     84		event_report(&events[i]);
     85	}
     86
     87	/*
     88	 * We should see that all events have enabled == running. That
     89	 * shows that they were all on the PMU at once.
     90	 */
     91	for (i = 0; i < 4; i++)
     92		FAIL_IF(events[i].result.running != events[i].result.enabled);
     93
     94	/*
     95	 * We can also check that the result for instructions is >= all the
     96	 * other counts. That's because it is counting all instructions while
     97	 * the others are counting a subset.
     98	 */
     99	for (i = 1; i < 4; i++)
    100		FAIL_IF(events[0].result.value < events[i].result.value);
    101
    102	for (i = 0; i < 4; i++)
    103		event_close(&events[i]);
    104
    105	return 0;
    106}
    107
    108int main(void)
    109{
    110	return test_harness(per_event_excludes, "per_event_excludes");
    111}