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

pfm.c (3633B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Test support for libpfm4 event encodings.
      4 *
      5 * Copyright 2020 Google LLC.
      6 */
      7#include "tests.h"
      8#include "util/debug.h"
      9#include "util/evlist.h"
     10#include "util/pfm.h"
     11
     12#include <linux/kernel.h>
     13
     14#ifdef HAVE_LIBPFM
     15static int count_pfm_events(struct perf_evlist *evlist)
     16{
     17	struct perf_evsel *evsel;
     18	int count = 0;
     19
     20	perf_evlist__for_each_entry(evlist, evsel) {
     21		count++;
     22	}
     23	return count;
     24}
     25
     26static int test__pfm_events(struct test_suite *test __maybe_unused,
     27			    int subtest __maybe_unused)
     28{
     29	struct evlist *evlist;
     30	struct option opt;
     31	size_t i;
     32	const struct {
     33		const char *events;
     34		int nr_events;
     35	} table[] = {
     36		{
     37			.events = "",
     38			.nr_events = 0,
     39		},
     40		{
     41			.events = "instructions",
     42			.nr_events = 1,
     43		},
     44		{
     45			.events = "instructions,cycles",
     46			.nr_events = 2,
     47		},
     48		{
     49			.events = "stereolab",
     50			.nr_events = 0,
     51		},
     52		{
     53			.events = "instructions,instructions",
     54			.nr_events = 2,
     55		},
     56		{
     57			.events = "stereolab,instructions",
     58			.nr_events = 0,
     59		},
     60		{
     61			.events = "instructions,stereolab",
     62			.nr_events = 1,
     63		},
     64	};
     65
     66	for (i = 0; i < ARRAY_SIZE(table); i++) {
     67		evlist = evlist__new();
     68		if (evlist == NULL)
     69			return -ENOMEM;
     70
     71		opt.value = evlist;
     72		parse_libpfm_events_option(&opt,
     73					table[i].events,
     74					0);
     75		TEST_ASSERT_EQUAL(table[i].events,
     76				count_pfm_events(&evlist->core),
     77				table[i].nr_events);
     78		TEST_ASSERT_EQUAL(table[i].events,
     79				evlist->core.nr_groups,
     80				0);
     81
     82		evlist__delete(evlist);
     83	}
     84	return 0;
     85}
     86
     87static int test__pfm_group(struct test_suite *test __maybe_unused,
     88			   int subtest __maybe_unused)
     89{
     90	struct evlist *evlist;
     91	struct option opt;
     92	size_t i;
     93	const struct {
     94		const char *events;
     95		int nr_events;
     96		int nr_groups;
     97	} table[] = {
     98		{
     99			.events = "{},",
    100			.nr_events = 0,
    101			.nr_groups = 0,
    102		},
    103		{
    104			.events = "{instructions}",
    105			.nr_events = 1,
    106			.nr_groups = 1,
    107		},
    108		{
    109			.events = "{instructions},{}",
    110			.nr_events = 1,
    111			.nr_groups = 1,
    112		},
    113		{
    114			.events = "{},{instructions}",
    115			.nr_events = 1,
    116			.nr_groups = 1,
    117		},
    118		{
    119			.events = "{instructions},{instructions}",
    120			.nr_events = 2,
    121			.nr_groups = 2,
    122		},
    123		{
    124			.events = "{instructions,cycles},{instructions,cycles}",
    125			.nr_events = 4,
    126			.nr_groups = 2,
    127		},
    128		{
    129			.events = "{stereolab}",
    130			.nr_events = 0,
    131			.nr_groups = 0,
    132		},
    133		{
    134			.events =
    135			"{instructions,cycles},{instructions,stereolab}",
    136			.nr_events = 3,
    137			.nr_groups = 1,
    138		},
    139		{
    140			.events = "instructions}",
    141			.nr_events = 1,
    142			.nr_groups = 0,
    143		},
    144		{
    145			.events = "{{instructions}}",
    146			.nr_events = 0,
    147			.nr_groups = 0,
    148		},
    149	};
    150
    151	for (i = 0; i < ARRAY_SIZE(table); i++) {
    152		evlist = evlist__new();
    153		if (evlist == NULL)
    154			return -ENOMEM;
    155
    156		opt.value = evlist;
    157		parse_libpfm_events_option(&opt,
    158					table[i].events,
    159					0);
    160		TEST_ASSERT_EQUAL(table[i].events,
    161				count_pfm_events(&evlist->core),
    162				table[i].nr_events);
    163		TEST_ASSERT_EQUAL(table[i].events,
    164				evlist->core.nr_groups,
    165				table[i].nr_groups);
    166
    167		evlist__delete(evlist);
    168	}
    169	return 0;
    170}
    171#else
    172static int test__pfm_events(struct test_suite *test __maybe_unused,
    173			    int subtest __maybe_unused)
    174{
    175	return TEST_SKIP;
    176}
    177
    178static int test__pfm_group(struct test_suite *test __maybe_unused,
    179			   int subtest __maybe_unused)
    180{
    181	return TEST_SKIP;
    182}
    183#endif
    184
    185static struct test_case pfm_tests[] = {
    186	TEST_CASE_REASON("test of individual --pfm-events", pfm_events, "not compiled in"),
    187	TEST_CASE_REASON("test groups of --pfm-events", pfm_group, "not compiled in"),
    188	{ .name = NULL, }
    189};
    190
    191struct test_suite suite__pfm = {
    192	.desc = "Test libpfm4 support",
    193	.test_cases = pfm_tests,
    194};