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 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