89 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*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 we can setup an EBB on our child. Nothing interesting happens, because19 * even though the event is enabled and running the child hasn't enabled the20 * actual delivery of the EBBs.21 */22 23static int victim_child(union pipe read_pipe, union pipe write_pipe)24{25 int i;26 27 FAIL_IF(wait_for_parent(read_pipe));28 FAIL_IF(notify_parent(write_pipe));29 30 /* Parent creates EBB event */31 32 FAIL_IF(wait_for_parent(read_pipe));33 FAIL_IF(notify_parent(write_pipe));34 35 /* Check the EBB is enabled by writing PMC1 */36 write_pmc1();37 38 /* EBB event is enabled here */39 for (i = 0; i < 1000000; i++) ;40 41 return 0;42}43 44int ebb_on_child(void)45{46 union pipe read_pipe, write_pipe;47 struct event event;48 pid_t pid;49 50 SKIP_IF(!ebb_is_supported());51 52 FAIL_IF(pipe(read_pipe.fds) == -1);53 FAIL_IF(pipe(write_pipe.fds) == -1);54 55 pid = fork();56 if (pid == 0) {57 /* NB order of pipes looks reversed */58 exit(victim_child(write_pipe, read_pipe));59 }60 61 FAIL_IF(sync_with_child(read_pipe, write_pipe));62 63 /* Child is running now */64 65 event_init_named(&event, 0x1001e, "cycles");66 event_leader_ebb_init(&event);67 68 event.attr.exclude_kernel = 1;69 event.attr.exclude_hv = 1;70 event.attr.exclude_idle = 1;71 72 FAIL_IF(event_open_with_pid(&event, pid));73 FAIL_IF(ebb_event_enable(&event));74 75 FAIL_IF(sync_with_child(read_pipe, write_pipe));76 77 /* Child should just exit happily */78 FAIL_IF(wait_for_child(pid));79 80 event_close(&event);81 82 return 0;83}84 85int main(void)86{87 return test_harness(ebb_on_child, "ebb_on_child");88}89