15a6bef47SJiri Olsa /* 25a6bef47SJiri Olsa * Inspired by breakpoint overflow test done by 35a6bef47SJiri Olsa * Vince Weaver <vincent.weaver@maine.edu> for perf_event_tests 45a6bef47SJiri Olsa * (git://github.com/deater/perf_event_tests) 55a6bef47SJiri Olsa */ 65a6bef47SJiri Olsa 7b3539d21SSukadev Bhattiprolu /* 8b3539d21SSukadev Bhattiprolu * Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select 9b3539d21SSukadev Bhattiprolu * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu. 10b3539d21SSukadev Bhattiprolu */ 11b3539d21SSukadev Bhattiprolu #define __SANE_USERSPACE_TYPES__ 12b3539d21SSukadev Bhattiprolu 135a6bef47SJiri Olsa #include <stdlib.h> 145a6bef47SJiri Olsa #include <stdio.h> 155a6bef47SJiri Olsa #include <unistd.h> 165a6bef47SJiri Olsa #include <string.h> 175a6bef47SJiri Olsa #include <sys/ioctl.h> 185a6bef47SJiri Olsa #include <time.h> 195a6bef47SJiri Olsa #include <fcntl.h> 205a6bef47SJiri Olsa #include <signal.h> 215a6bef47SJiri Olsa #include <sys/mman.h> 225a6bef47SJiri Olsa #include <linux/compiler.h> 235a6bef47SJiri Olsa #include <linux/hw_breakpoint.h> 245a6bef47SJiri Olsa 255a6bef47SJiri Olsa #include "tests.h" 265a6bef47SJiri Olsa #include "debug.h" 275a6bef47SJiri Olsa #include "perf.h" 28*57480d2cSYann Droneaud #include "cloexec.h" 295a6bef47SJiri Olsa 305a6bef47SJiri Olsa static int fd1; 315a6bef47SJiri Olsa static int fd2; 325a6bef47SJiri Olsa static int overflows; 335a6bef47SJiri Olsa 345a6bef47SJiri Olsa __attribute__ ((noinline)) 355a6bef47SJiri Olsa static int test_function(void) 365a6bef47SJiri Olsa { 375a6bef47SJiri Olsa return time(NULL); 385a6bef47SJiri Olsa } 395a6bef47SJiri Olsa 405a6bef47SJiri Olsa static void sig_handler(int signum __maybe_unused, 415a6bef47SJiri Olsa siginfo_t *oh __maybe_unused, 425a6bef47SJiri Olsa void *uc __maybe_unused) 435a6bef47SJiri Olsa { 445a6bef47SJiri Olsa overflows++; 455a6bef47SJiri Olsa 465a6bef47SJiri Olsa if (overflows > 10) { 475a6bef47SJiri Olsa /* 485a6bef47SJiri Olsa * This should be executed only once during 495a6bef47SJiri Olsa * this test, if we are here for the 10th 505a6bef47SJiri Olsa * time, consider this the recursive issue. 515a6bef47SJiri Olsa * 525a6bef47SJiri Olsa * We can get out of here by disable events, 535a6bef47SJiri Olsa * so no new SIGIO is delivered. 545a6bef47SJiri Olsa */ 555a6bef47SJiri Olsa ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0); 565a6bef47SJiri Olsa ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0); 575a6bef47SJiri Olsa } 585a6bef47SJiri Olsa } 595a6bef47SJiri Olsa 605a6bef47SJiri Olsa static int bp_event(void *fn, int setup_signal) 615a6bef47SJiri Olsa { 625a6bef47SJiri Olsa struct perf_event_attr pe; 635a6bef47SJiri Olsa int fd; 645a6bef47SJiri Olsa 655a6bef47SJiri Olsa memset(&pe, 0, sizeof(struct perf_event_attr)); 665a6bef47SJiri Olsa pe.type = PERF_TYPE_BREAKPOINT; 675a6bef47SJiri Olsa pe.size = sizeof(struct perf_event_attr); 685a6bef47SJiri Olsa 695a6bef47SJiri Olsa pe.config = 0; 705a6bef47SJiri Olsa pe.bp_type = HW_BREAKPOINT_X; 715a6bef47SJiri Olsa pe.bp_addr = (unsigned long) fn; 725a6bef47SJiri Olsa pe.bp_len = sizeof(long); 735a6bef47SJiri Olsa 745a6bef47SJiri Olsa pe.sample_period = 1; 755a6bef47SJiri Olsa pe.sample_type = PERF_SAMPLE_IP; 765a6bef47SJiri Olsa pe.wakeup_events = 1; 775a6bef47SJiri Olsa 785a6bef47SJiri Olsa pe.disabled = 1; 795a6bef47SJiri Olsa pe.exclude_kernel = 1; 805a6bef47SJiri Olsa pe.exclude_hv = 1; 815a6bef47SJiri Olsa 82*57480d2cSYann Droneaud fd = sys_perf_event_open(&pe, 0, -1, -1, 83*57480d2cSYann Droneaud perf_event_open_cloexec_flag()); 845a6bef47SJiri Olsa if (fd < 0) { 855a6bef47SJiri Olsa pr_debug("failed opening event %llx\n", pe.config); 865a6bef47SJiri Olsa return TEST_FAIL; 875a6bef47SJiri Olsa } 885a6bef47SJiri Olsa 895a6bef47SJiri Olsa if (setup_signal) { 905a6bef47SJiri Olsa fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC); 915a6bef47SJiri Olsa fcntl(fd, F_SETSIG, SIGIO); 925a6bef47SJiri Olsa fcntl(fd, F_SETOWN, getpid()); 935a6bef47SJiri Olsa } 945a6bef47SJiri Olsa 955a6bef47SJiri Olsa ioctl(fd, PERF_EVENT_IOC_RESET, 0); 965a6bef47SJiri Olsa 975a6bef47SJiri Olsa return fd; 985a6bef47SJiri Olsa } 995a6bef47SJiri Olsa 1005a6bef47SJiri Olsa static long long bp_count(int fd) 1015a6bef47SJiri Olsa { 1025a6bef47SJiri Olsa long long count; 1035a6bef47SJiri Olsa int ret; 1045a6bef47SJiri Olsa 1055a6bef47SJiri Olsa ret = read(fd, &count, sizeof(long long)); 1065a6bef47SJiri Olsa if (ret != sizeof(long long)) { 1075a6bef47SJiri Olsa pr_debug("failed to read: %d\n", ret); 1085a6bef47SJiri Olsa return TEST_FAIL; 1095a6bef47SJiri Olsa } 1105a6bef47SJiri Olsa 1115a6bef47SJiri Olsa return count; 1125a6bef47SJiri Olsa } 1135a6bef47SJiri Olsa 1145a6bef47SJiri Olsa int test__bp_signal(void) 1155a6bef47SJiri Olsa { 1165a6bef47SJiri Olsa struct sigaction sa; 1175a6bef47SJiri Olsa long long count1, count2; 1185a6bef47SJiri Olsa 1195a6bef47SJiri Olsa /* setup SIGIO signal handler */ 1205a6bef47SJiri Olsa memset(&sa, 0, sizeof(struct sigaction)); 1215a6bef47SJiri Olsa sa.sa_sigaction = (void *) sig_handler; 1225a6bef47SJiri Olsa sa.sa_flags = SA_SIGINFO; 1235a6bef47SJiri Olsa 1245a6bef47SJiri Olsa if (sigaction(SIGIO, &sa, NULL) < 0) { 1255a6bef47SJiri Olsa pr_debug("failed setting up signal handler\n"); 1265a6bef47SJiri Olsa return TEST_FAIL; 1275a6bef47SJiri Olsa } 1285a6bef47SJiri Olsa 1295a6bef47SJiri Olsa /* 1305a6bef47SJiri Olsa * We create following events: 1315a6bef47SJiri Olsa * 1325a6bef47SJiri Olsa * fd1 - breakpoint event on test_function with SIGIO 1335a6bef47SJiri Olsa * signal configured. We should get signal 1345a6bef47SJiri Olsa * notification each time the breakpoint is hit 1355a6bef47SJiri Olsa * 1365a6bef47SJiri Olsa * fd2 - breakpoint event on sig_handler without SIGIO 1375a6bef47SJiri Olsa * configured. 1385a6bef47SJiri Olsa * 1395a6bef47SJiri Olsa * Following processing should happen: 1405a6bef47SJiri Olsa * - execute test_function 1415a6bef47SJiri Olsa * - fd1 event breakpoint hit -> count1 == 1 1425a6bef47SJiri Olsa * - SIGIO is delivered -> overflows == 1 1435a6bef47SJiri Olsa * - fd2 event breakpoint hit -> count2 == 1 1445a6bef47SJiri Olsa * 1455a6bef47SJiri Olsa * The test case check following error conditions: 1465a6bef47SJiri Olsa * - we get stuck in signal handler because of debug 1475a6bef47SJiri Olsa * exception being triggered receursively due to 1485a6bef47SJiri Olsa * the wrong RF EFLAG management 1495a6bef47SJiri Olsa * 1505a6bef47SJiri Olsa * - we never trigger the sig_handler breakpoint due 1515a6bef47SJiri Olsa * to the rong RF EFLAG management 1525a6bef47SJiri Olsa * 1535a6bef47SJiri Olsa */ 1545a6bef47SJiri Olsa 1555a6bef47SJiri Olsa fd1 = bp_event(test_function, 1); 1565a6bef47SJiri Olsa fd2 = bp_event(sig_handler, 0); 1575a6bef47SJiri Olsa 1585a6bef47SJiri Olsa ioctl(fd1, PERF_EVENT_IOC_ENABLE, 0); 1595a6bef47SJiri Olsa ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0); 1605a6bef47SJiri Olsa 1615a6bef47SJiri Olsa /* 1625a6bef47SJiri Olsa * Kick off the test by trigering 'fd1' 1635a6bef47SJiri Olsa * breakpoint. 1645a6bef47SJiri Olsa */ 1655a6bef47SJiri Olsa test_function(); 1665a6bef47SJiri Olsa 1675a6bef47SJiri Olsa ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0); 1685a6bef47SJiri Olsa ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0); 1695a6bef47SJiri Olsa 1705a6bef47SJiri Olsa count1 = bp_count(fd1); 1715a6bef47SJiri Olsa count2 = bp_count(fd2); 1725a6bef47SJiri Olsa 1735a6bef47SJiri Olsa close(fd1); 1745a6bef47SJiri Olsa close(fd2); 1755a6bef47SJiri Olsa 1765a6bef47SJiri Olsa pr_debug("count1 %lld, count2 %lld, overflow %d\n", 1775a6bef47SJiri Olsa count1, count2, overflows); 1785a6bef47SJiri Olsa 1795a6bef47SJiri Olsa if (count1 != 1) { 1805a6bef47SJiri Olsa if (count1 == 11) 1815a6bef47SJiri Olsa pr_debug("failed: RF EFLAG recursion issue detected\n"); 1825a6bef47SJiri Olsa else 1835a6bef47SJiri Olsa pr_debug("failed: wrong count for bp1%lld\n", count1); 1845a6bef47SJiri Olsa } 1855a6bef47SJiri Olsa 1865a6bef47SJiri Olsa if (overflows != 1) 1875a6bef47SJiri Olsa pr_debug("failed: wrong overflow hit\n"); 1885a6bef47SJiri Olsa 1895a6bef47SJiri Olsa if (count2 != 1) 1905a6bef47SJiri Olsa pr_debug("failed: wrong count for bp2\n"); 1915a6bef47SJiri Olsa 1925a6bef47SJiri Olsa return count1 == 1 && overflows == 1 && count2 == 1 ? 1935a6bef47SJiri Olsa TEST_OK : TEST_FAIL; 1945a6bef47SJiri Olsa } 195