1/* 2 * Copyright 2014, Michael Ellerman, IBM Corp. 3 * Licensed under GPLv2. 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, because 19 * even though the event is enabled and running the child hasn't enabled the 20 * 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 FAIL_IF(pipe(read_pipe.fds) == -1); 51 FAIL_IF(pipe(write_pipe.fds) == -1); 52 53 pid = fork(); 54 if (pid == 0) { 55 /* NB order of pipes looks reversed */ 56 exit(victim_child(write_pipe, read_pipe)); 57 } 58 59 FAIL_IF(sync_with_child(read_pipe, write_pipe)); 60 61 /* Child is running now */ 62 63 event_init_named(&event, 0x1001e, "cycles"); 64 event_leader_ebb_init(&event); 65 66 event.attr.exclude_kernel = 1; 67 event.attr.exclude_hv = 1; 68 event.attr.exclude_idle = 1; 69 70 FAIL_IF(event_open_with_pid(&event, pid)); 71 FAIL_IF(ebb_event_enable(&event)); 72 73 FAIL_IF(sync_with_child(read_pipe, write_pipe)); 74 75 /* Child should just exit happily */ 76 FAIL_IF(wait_for_child(pid)); 77 78 event_close(&event); 79 80 return 0; 81} 82 83int main(void) 84{ 85 return test_harness(ebb_on_child, "ebb_on_child"); 86} 87