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

sample-parsing.c (2879B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2#include <stdbool.h>
      3#include <inttypes.h>
      4#include <stdlib.h>
      5#include <string.h>
      6#include <linux/bitops.h>
      7#include <linux/kernel.h>
      8#include <linux/types.h>
      9
     10#include "event.h"
     11#include "evsel.h"
     12#include "debug.h"
     13#include "util/synthetic-events.h"
     14
     15#include "tests/tests.h"
     16#include "arch-tests.h"
     17
     18#define COMP(m) do {					\
     19	if (s1->m != s2->m) {				\
     20		pr_debug("Samples differ at '"#m"'\n");	\
     21		return false;				\
     22	}						\
     23} while (0)
     24
     25static bool samples_same(const struct perf_sample *s1,
     26			 const struct perf_sample *s2,
     27			 u64 type)
     28{
     29	if (type & PERF_SAMPLE_WEIGHT_STRUCT)
     30		COMP(ins_lat);
     31
     32	return true;
     33}
     34
     35static int do_test(u64 sample_type)
     36{
     37	struct evsel evsel = {
     38		.needs_swap = false,
     39		.core = {
     40			. attr = {
     41				.sample_type = sample_type,
     42				.read_format = 0,
     43			},
     44		},
     45	};
     46	union perf_event *event;
     47	struct perf_sample sample = {
     48		.weight		= 101,
     49		.ins_lat        = 102,
     50	};
     51	struct perf_sample sample_out;
     52	size_t i, sz, bufsz;
     53	int err, ret = -1;
     54
     55	sz = perf_event__sample_event_size(&sample, sample_type, 0);
     56	bufsz = sz + 4096; /* Add a bit for overrun checking */
     57	event = malloc(bufsz);
     58	if (!event) {
     59		pr_debug("malloc failed\n");
     60		return -1;
     61	}
     62
     63	memset(event, 0xff, bufsz);
     64	event->header.type = PERF_RECORD_SAMPLE;
     65	event->header.misc = 0;
     66	event->header.size = sz;
     67
     68	err = perf_event__synthesize_sample(event, sample_type, 0, &sample);
     69	if (err) {
     70		pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
     71			 "perf_event__synthesize_sample", sample_type, err);
     72		goto out_free;
     73	}
     74
     75	/* The data does not contain 0xff so we use that to check the size */
     76	for (i = bufsz; i > 0; i--) {
     77		if (*(i - 1 + (u8 *)event) != 0xff)
     78			break;
     79	}
     80	if (i != sz) {
     81		pr_debug("Event size mismatch: actual %zu vs expected %zu\n",
     82			 i, sz);
     83		goto out_free;
     84	}
     85
     86	evsel.sample_size = __evsel__sample_size(sample_type);
     87
     88	err = evsel__parse_sample(&evsel, event, &sample_out);
     89	if (err) {
     90		pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
     91			 "evsel__parse_sample", sample_type, err);
     92		goto out_free;
     93	}
     94
     95	if (!samples_same(&sample, &sample_out, sample_type)) {
     96		pr_debug("parsing failed for sample_type %#"PRIx64"\n",
     97			 sample_type);
     98		goto out_free;
     99	}
    100
    101	ret = 0;
    102out_free:
    103	free(event);
    104
    105	return ret;
    106}
    107
    108/**
    109 * test__x86_sample_parsing - test X86 specific sample parsing
    110 *
    111 * This function implements a test that synthesizes a sample event, parses it
    112 * and then checks that the parsed sample matches the original sample. If the
    113 * test passes %0 is returned, otherwise %-1 is returned.
    114 *
    115 * For now, the PERF_SAMPLE_WEIGHT_STRUCT is the only X86 specific sample type.
    116 * The test only checks the PERF_SAMPLE_WEIGHT_STRUCT type.
    117 */
    118int test__x86_sample_parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
    119{
    120	return do_test(PERF_SAMPLE_WEIGHT_STRUCT);
    121}