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

task_event_vs_ebb_test.c (1778B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright 2014, Michael Ellerman, IBM Corp.
      4 */
      5
      6#include <signal.h>
      7#include <stdio.h>
      8#include <stdlib.h>
      9#include <stdbool.h>
     10#include <sys/types.h>
     11#include <sys/wait.h>
     12#include <unistd.h>
     13
     14#include "ebb.h"
     15
     16
     17/*
     18 * Tests a per-task event vs an EBB - in that order. The EBB should push the
     19 * per-task event off the PMU.
     20 */
     21
     22static int setup_child_event(struct event *event, pid_t child_pid)
     23{
     24	event_init_named(event, 0x400FA, "PM_RUN_INST_CMPL");
     25
     26	event->attr.exclude_kernel = 1;
     27	event->attr.exclude_hv = 1;
     28	event->attr.exclude_idle = 1;
     29
     30	FAIL_IF(event_open_with_pid(event, child_pid));
     31	FAIL_IF(event_enable(event));
     32
     33	return 0;
     34}
     35
     36int task_event_vs_ebb(void)
     37{
     38	union pipe read_pipe, write_pipe;
     39	struct event event;
     40	pid_t pid;
     41	int rc;
     42
     43	SKIP_IF(!ebb_is_supported());
     44
     45	FAIL_IF(pipe(read_pipe.fds) == -1);
     46	FAIL_IF(pipe(write_pipe.fds) == -1);
     47
     48	pid = fork();
     49	if (pid == 0) {
     50		/* NB order of pipes looks reversed */
     51		exit(ebb_child(write_pipe, read_pipe));
     52	}
     53
     54	/* We setup the task event first */
     55	rc = setup_child_event(&event, pid);
     56	if (rc) {
     57		kill_child_and_wait(pid);
     58		return rc;
     59	}
     60
     61	/* Signal the child to install its EBB event and wait */
     62	if (sync_with_child(read_pipe, write_pipe))
     63		/* If it fails, wait for it to exit */
     64		goto wait;
     65
     66	/* Signal the child to run */
     67	FAIL_IF(sync_with_child(read_pipe, write_pipe));
     68
     69wait:
     70	/* The EBB event should push the task event off so the child should succeed */
     71	FAIL_IF(wait_for_child(pid));
     72	FAIL_IF(event_disable(&event));
     73	FAIL_IF(event_read(&event));
     74
     75	event_report(&event);
     76
     77	/* The task event may have run, or not so we can't assert anything about it */
     78
     79	return 0;
     80}
     81
     82int main(void)
     83{
     84	return test_harness(task_event_vs_ebb, "task_event_vs_ebb");
     85}