1*5a6bef47SJiri Olsa /* 2*5a6bef47SJiri Olsa * Inspired by breakpoint overflow test done by 3*5a6bef47SJiri Olsa * Vince Weaver <vincent.weaver@maine.edu> for perf_event_tests 4*5a6bef47SJiri Olsa * (git://github.com/deater/perf_event_tests) 5*5a6bef47SJiri Olsa */ 6*5a6bef47SJiri Olsa 7*5a6bef47SJiri Olsa #include <stdlib.h> 8*5a6bef47SJiri Olsa #include <stdio.h> 9*5a6bef47SJiri Olsa #include <unistd.h> 10*5a6bef47SJiri Olsa #include <string.h> 11*5a6bef47SJiri Olsa #include <sys/ioctl.h> 12*5a6bef47SJiri Olsa #include <time.h> 13*5a6bef47SJiri Olsa #include <fcntl.h> 14*5a6bef47SJiri Olsa #include <signal.h> 15*5a6bef47SJiri Olsa #include <sys/mman.h> 16*5a6bef47SJiri Olsa #include <linux/compiler.h> 17*5a6bef47SJiri Olsa #include <linux/hw_breakpoint.h> 18*5a6bef47SJiri Olsa 19*5a6bef47SJiri Olsa #include "tests.h" 20*5a6bef47SJiri Olsa #include "debug.h" 21*5a6bef47SJiri Olsa #include "perf.h" 22*5a6bef47SJiri Olsa 23*5a6bef47SJiri Olsa static int fd1; 24*5a6bef47SJiri Olsa static int fd2; 25*5a6bef47SJiri Olsa static int overflows; 26*5a6bef47SJiri Olsa 27*5a6bef47SJiri Olsa __attribute__ ((noinline)) 28*5a6bef47SJiri Olsa static int test_function(void) 29*5a6bef47SJiri Olsa { 30*5a6bef47SJiri Olsa return time(NULL); 31*5a6bef47SJiri Olsa } 32*5a6bef47SJiri Olsa 33*5a6bef47SJiri Olsa static void sig_handler(int signum __maybe_unused, 34*5a6bef47SJiri Olsa siginfo_t *oh __maybe_unused, 35*5a6bef47SJiri Olsa void *uc __maybe_unused) 36*5a6bef47SJiri Olsa { 37*5a6bef47SJiri Olsa overflows++; 38*5a6bef47SJiri Olsa 39*5a6bef47SJiri Olsa if (overflows > 10) { 40*5a6bef47SJiri Olsa /* 41*5a6bef47SJiri Olsa * This should be executed only once during 42*5a6bef47SJiri Olsa * this test, if we are here for the 10th 43*5a6bef47SJiri Olsa * time, consider this the recursive issue. 44*5a6bef47SJiri Olsa * 45*5a6bef47SJiri Olsa * We can get out of here by disable events, 46*5a6bef47SJiri Olsa * so no new SIGIO is delivered. 47*5a6bef47SJiri Olsa */ 48*5a6bef47SJiri Olsa ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0); 49*5a6bef47SJiri Olsa ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0); 50*5a6bef47SJiri Olsa } 51*5a6bef47SJiri Olsa } 52*5a6bef47SJiri Olsa 53*5a6bef47SJiri Olsa static int bp_event(void *fn, int setup_signal) 54*5a6bef47SJiri Olsa { 55*5a6bef47SJiri Olsa struct perf_event_attr pe; 56*5a6bef47SJiri Olsa int fd; 57*5a6bef47SJiri Olsa 58*5a6bef47SJiri Olsa memset(&pe, 0, sizeof(struct perf_event_attr)); 59*5a6bef47SJiri Olsa pe.type = PERF_TYPE_BREAKPOINT; 60*5a6bef47SJiri Olsa pe.size = sizeof(struct perf_event_attr); 61*5a6bef47SJiri Olsa 62*5a6bef47SJiri Olsa pe.config = 0; 63*5a6bef47SJiri Olsa pe.bp_type = HW_BREAKPOINT_X; 64*5a6bef47SJiri Olsa pe.bp_addr = (unsigned long) fn; 65*5a6bef47SJiri Olsa pe.bp_len = sizeof(long); 66*5a6bef47SJiri Olsa 67*5a6bef47SJiri Olsa pe.sample_period = 1; 68*5a6bef47SJiri Olsa pe.sample_type = PERF_SAMPLE_IP; 69*5a6bef47SJiri Olsa pe.wakeup_events = 1; 70*5a6bef47SJiri Olsa 71*5a6bef47SJiri Olsa pe.disabled = 1; 72*5a6bef47SJiri Olsa pe.exclude_kernel = 1; 73*5a6bef47SJiri Olsa pe.exclude_hv = 1; 74*5a6bef47SJiri Olsa 75*5a6bef47SJiri Olsa fd = sys_perf_event_open(&pe, 0, -1, -1, 0); 76*5a6bef47SJiri Olsa if (fd < 0) { 77*5a6bef47SJiri Olsa pr_debug("failed opening event %llx\n", pe.config); 78*5a6bef47SJiri Olsa return TEST_FAIL; 79*5a6bef47SJiri Olsa } 80*5a6bef47SJiri Olsa 81*5a6bef47SJiri Olsa if (setup_signal) { 82*5a6bef47SJiri Olsa fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC); 83*5a6bef47SJiri Olsa fcntl(fd, F_SETSIG, SIGIO); 84*5a6bef47SJiri Olsa fcntl(fd, F_SETOWN, getpid()); 85*5a6bef47SJiri Olsa } 86*5a6bef47SJiri Olsa 87*5a6bef47SJiri Olsa ioctl(fd, PERF_EVENT_IOC_RESET, 0); 88*5a6bef47SJiri Olsa 89*5a6bef47SJiri Olsa return fd; 90*5a6bef47SJiri Olsa } 91*5a6bef47SJiri Olsa 92*5a6bef47SJiri Olsa static long long bp_count(int fd) 93*5a6bef47SJiri Olsa { 94*5a6bef47SJiri Olsa long long count; 95*5a6bef47SJiri Olsa int ret; 96*5a6bef47SJiri Olsa 97*5a6bef47SJiri Olsa ret = read(fd, &count, sizeof(long long)); 98*5a6bef47SJiri Olsa if (ret != sizeof(long long)) { 99*5a6bef47SJiri Olsa pr_debug("failed to read: %d\n", ret); 100*5a6bef47SJiri Olsa return TEST_FAIL; 101*5a6bef47SJiri Olsa } 102*5a6bef47SJiri Olsa 103*5a6bef47SJiri Olsa return count; 104*5a6bef47SJiri Olsa } 105*5a6bef47SJiri Olsa 106*5a6bef47SJiri Olsa int test__bp_signal(void) 107*5a6bef47SJiri Olsa { 108*5a6bef47SJiri Olsa struct sigaction sa; 109*5a6bef47SJiri Olsa long long count1, count2; 110*5a6bef47SJiri Olsa 111*5a6bef47SJiri Olsa /* setup SIGIO signal handler */ 112*5a6bef47SJiri Olsa memset(&sa, 0, sizeof(struct sigaction)); 113*5a6bef47SJiri Olsa sa.sa_sigaction = (void *) sig_handler; 114*5a6bef47SJiri Olsa sa.sa_flags = SA_SIGINFO; 115*5a6bef47SJiri Olsa 116*5a6bef47SJiri Olsa if (sigaction(SIGIO, &sa, NULL) < 0) { 117*5a6bef47SJiri Olsa pr_debug("failed setting up signal handler\n"); 118*5a6bef47SJiri Olsa return TEST_FAIL; 119*5a6bef47SJiri Olsa } 120*5a6bef47SJiri Olsa 121*5a6bef47SJiri Olsa /* 122*5a6bef47SJiri Olsa * We create following events: 123*5a6bef47SJiri Olsa * 124*5a6bef47SJiri Olsa * fd1 - breakpoint event on test_function with SIGIO 125*5a6bef47SJiri Olsa * signal configured. We should get signal 126*5a6bef47SJiri Olsa * notification each time the breakpoint is hit 127*5a6bef47SJiri Olsa * 128*5a6bef47SJiri Olsa * fd2 - breakpoint event on sig_handler without SIGIO 129*5a6bef47SJiri Olsa * configured. 130*5a6bef47SJiri Olsa * 131*5a6bef47SJiri Olsa * Following processing should happen: 132*5a6bef47SJiri Olsa * - execute test_function 133*5a6bef47SJiri Olsa * - fd1 event breakpoint hit -> count1 == 1 134*5a6bef47SJiri Olsa * - SIGIO is delivered -> overflows == 1 135*5a6bef47SJiri Olsa * - fd2 event breakpoint hit -> count2 == 1 136*5a6bef47SJiri Olsa * 137*5a6bef47SJiri Olsa * The test case check following error conditions: 138*5a6bef47SJiri Olsa * - we get stuck in signal handler because of debug 139*5a6bef47SJiri Olsa * exception being triggered receursively due to 140*5a6bef47SJiri Olsa * the wrong RF EFLAG management 141*5a6bef47SJiri Olsa * 142*5a6bef47SJiri Olsa * - we never trigger the sig_handler breakpoint due 143*5a6bef47SJiri Olsa * to the rong RF EFLAG management 144*5a6bef47SJiri Olsa * 145*5a6bef47SJiri Olsa */ 146*5a6bef47SJiri Olsa 147*5a6bef47SJiri Olsa fd1 = bp_event(test_function, 1); 148*5a6bef47SJiri Olsa fd2 = bp_event(sig_handler, 0); 149*5a6bef47SJiri Olsa 150*5a6bef47SJiri Olsa ioctl(fd1, PERF_EVENT_IOC_ENABLE, 0); 151*5a6bef47SJiri Olsa ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0); 152*5a6bef47SJiri Olsa 153*5a6bef47SJiri Olsa /* 154*5a6bef47SJiri Olsa * Kick off the test by trigering 'fd1' 155*5a6bef47SJiri Olsa * breakpoint. 156*5a6bef47SJiri Olsa */ 157*5a6bef47SJiri Olsa test_function(); 158*5a6bef47SJiri Olsa 159*5a6bef47SJiri Olsa ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0); 160*5a6bef47SJiri Olsa ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0); 161*5a6bef47SJiri Olsa 162*5a6bef47SJiri Olsa count1 = bp_count(fd1); 163*5a6bef47SJiri Olsa count2 = bp_count(fd2); 164*5a6bef47SJiri Olsa 165*5a6bef47SJiri Olsa close(fd1); 166*5a6bef47SJiri Olsa close(fd2); 167*5a6bef47SJiri Olsa 168*5a6bef47SJiri Olsa pr_debug("count1 %lld, count2 %lld, overflow %d\n", 169*5a6bef47SJiri Olsa count1, count2, overflows); 170*5a6bef47SJiri Olsa 171*5a6bef47SJiri Olsa if (count1 != 1) { 172*5a6bef47SJiri Olsa if (count1 == 11) 173*5a6bef47SJiri Olsa pr_debug("failed: RF EFLAG recursion issue detected\n"); 174*5a6bef47SJiri Olsa else 175*5a6bef47SJiri Olsa pr_debug("failed: wrong count for bp1%lld\n", count1); 176*5a6bef47SJiri Olsa } 177*5a6bef47SJiri Olsa 178*5a6bef47SJiri Olsa if (overflows != 1) 179*5a6bef47SJiri Olsa pr_debug("failed: wrong overflow hit\n"); 180*5a6bef47SJiri Olsa 181*5a6bef47SJiri Olsa if (count2 != 1) 182*5a6bef47SJiri Olsa pr_debug("failed: wrong count for bp2\n"); 183*5a6bef47SJiri Olsa 184*5a6bef47SJiri Olsa return count1 == 1 && overflows == 1 && count2 == 1 ? 185*5a6bef47SJiri Olsa TEST_OK : TEST_FAIL; 186*5a6bef47SJiri Olsa } 187