1 /* 2 * Inspired by breakpoint overflow test done by 3 * Vince Weaver <vincent.weaver@maine.edu> for perf_event_tests 4 * (git://github.com/deater/perf_event_tests) 5 */ 6 7 /* 8 * Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select 9 * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu. 10 */ 11 #define __SANE_USERSPACE_TYPES__ 12 13 #include <stdlib.h> 14 #include <stdio.h> 15 #include <unistd.h> 16 #include <string.h> 17 #include <sys/ioctl.h> 18 #include <time.h> 19 #include <fcntl.h> 20 #include <signal.h> 21 #include <sys/mman.h> 22 #include <linux/compiler.h> 23 #include <linux/hw_breakpoint.h> 24 25 #include "tests.h" 26 #include "debug.h" 27 #include "perf.h" 28 #include "cloexec.h" 29 30 static int fd1; 31 static int fd2; 32 static int fd3; 33 static int overflows; 34 static int overflows_2; 35 36 volatile long the_var; 37 38 39 /* 40 * Use ASM to ensure watchpoint and breakpoint can be triggered 41 * at one instruction. 42 */ 43 #if defined (__x86_64__) 44 extern void __test_function(volatile long *ptr); 45 asm ( 46 ".globl __test_function\n" 47 "__test_function:\n" 48 "incq (%rdi)\n" 49 "ret\n"); 50 #elif defined (__aarch64__) 51 extern void __test_function(volatile long *ptr); 52 asm ( 53 ".globl __test_function\n" 54 "__test_function:\n" 55 "str x30, [x0]\n" 56 "ret\n"); 57 58 #else 59 static void __test_function(volatile long *ptr) 60 { 61 *ptr = 0x1234; 62 } 63 #endif 64 65 static noinline int test_function(void) 66 { 67 __test_function(&the_var); 68 the_var++; 69 return time(NULL); 70 } 71 72 static void sig_handler_2(int signum __maybe_unused, 73 siginfo_t *oh __maybe_unused, 74 void *uc __maybe_unused) 75 { 76 overflows_2++; 77 if (overflows_2 > 10) { 78 ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0); 79 ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0); 80 ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0); 81 } 82 } 83 84 static void sig_handler(int signum __maybe_unused, 85 siginfo_t *oh __maybe_unused, 86 void *uc __maybe_unused) 87 { 88 overflows++; 89 90 if (overflows > 10) { 91 /* 92 * This should be executed only once during 93 * this test, if we are here for the 10th 94 * time, consider this the recursive issue. 95 * 96 * We can get out of here by disable events, 97 * so no new SIGIO is delivered. 98 */ 99 ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0); 100 ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0); 101 ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0); 102 } 103 } 104 105 static int __event(bool is_x, void *addr, int sig) 106 { 107 struct perf_event_attr pe; 108 int fd; 109 110 memset(&pe, 0, sizeof(struct perf_event_attr)); 111 pe.type = PERF_TYPE_BREAKPOINT; 112 pe.size = sizeof(struct perf_event_attr); 113 114 pe.config = 0; 115 pe.bp_type = is_x ? HW_BREAKPOINT_X : HW_BREAKPOINT_W; 116 pe.bp_addr = (unsigned long) addr; 117 pe.bp_len = sizeof(long); 118 119 pe.sample_period = 1; 120 pe.sample_type = PERF_SAMPLE_IP; 121 pe.wakeup_events = 1; 122 123 pe.disabled = 1; 124 pe.exclude_kernel = 1; 125 pe.exclude_hv = 1; 126 127 fd = sys_perf_event_open(&pe, 0, -1, -1, 128 perf_event_open_cloexec_flag()); 129 if (fd < 0) { 130 pr_debug("failed opening event %llx\n", pe.config); 131 return TEST_FAIL; 132 } 133 134 fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC); 135 fcntl(fd, F_SETSIG, sig); 136 fcntl(fd, F_SETOWN, getpid()); 137 138 ioctl(fd, PERF_EVENT_IOC_RESET, 0); 139 140 return fd; 141 } 142 143 static int bp_event(void *addr, int sig) 144 { 145 return __event(true, addr, sig); 146 } 147 148 static int wp_event(void *addr, int sig) 149 { 150 return __event(false, addr, sig); 151 } 152 153 static long long bp_count(int fd) 154 { 155 long long count; 156 int ret; 157 158 ret = read(fd, &count, sizeof(long long)); 159 if (ret != sizeof(long long)) { 160 pr_debug("failed to read: %d\n", ret); 161 return TEST_FAIL; 162 } 163 164 return count; 165 } 166 167 int test__bp_signal(int subtest __maybe_unused) 168 { 169 struct sigaction sa; 170 long long count1, count2, count3; 171 172 /* setup SIGIO signal handler */ 173 memset(&sa, 0, sizeof(struct sigaction)); 174 sa.sa_sigaction = (void *) sig_handler; 175 sa.sa_flags = SA_SIGINFO; 176 177 if (sigaction(SIGIO, &sa, NULL) < 0) { 178 pr_debug("failed setting up signal handler\n"); 179 return TEST_FAIL; 180 } 181 182 sa.sa_sigaction = (void *) sig_handler_2; 183 if (sigaction(SIGUSR1, &sa, NULL) < 0) { 184 pr_debug("failed setting up signal handler 2\n"); 185 return TEST_FAIL; 186 } 187 188 /* 189 * We create following events: 190 * 191 * fd1 - breakpoint event on __test_function with SIGIO 192 * signal configured. We should get signal 193 * notification each time the breakpoint is hit 194 * 195 * fd2 - breakpoint event on sig_handler with SIGUSR1 196 * configured. We should get SIGUSR1 each time when 197 * breakpoint is hit 198 * 199 * fd3 - watchpoint event on __test_function with SIGIO 200 * configured. 201 * 202 * Following processing should happen: 203 * Exec: Action: Result: 204 * incq (%rdi) - fd1 event breakpoint hit -> count1 == 1 205 * - SIGIO is delivered 206 * sig_handler - fd2 event breakpoint hit -> count2 == 1 207 * - SIGUSR1 is delivered 208 * sig_handler_2 -> overflows_2 == 1 (nested signal) 209 * sys_rt_sigreturn - return from sig_handler_2 210 * overflows++ -> overflows = 1 211 * sys_rt_sigreturn - return from sig_handler 212 * incq (%rdi) - fd3 event watchpoint hit -> count3 == 1 (wp and bp in one insn) 213 * - SIGIO is delivered 214 * sig_handler - fd2 event breakpoint hit -> count2 == 2 215 * - SIGUSR1 is delivered 216 * sig_handler_2 -> overflows_2 == 2 (nested signal) 217 * sys_rt_sigreturn - return from sig_handler_2 218 * overflows++ -> overflows = 2 219 * sys_rt_sigreturn - return from sig_handler 220 * the_var++ - fd3 event watchpoint hit -> count3 == 2 (standalone watchpoint) 221 * - SIGIO is delivered 222 * sig_handler - fd2 event breakpoint hit -> count2 == 3 223 * - SIGUSR1 is delivered 224 * sig_handler_2 -> overflows_2 == 3 (nested signal) 225 * sys_rt_sigreturn - return from sig_handler_2 226 * overflows++ -> overflows == 3 227 * sys_rt_sigreturn - return from sig_handler 228 * 229 * The test case check following error conditions: 230 * - we get stuck in signal handler because of debug 231 * exception being triggered receursively due to 232 * the wrong RF EFLAG management 233 * 234 * - we never trigger the sig_handler breakpoint due 235 * to the rong RF EFLAG management 236 * 237 */ 238 239 fd1 = bp_event(__test_function, SIGIO); 240 fd2 = bp_event(sig_handler, SIGUSR1); 241 fd3 = wp_event((void *)&the_var, SIGIO); 242 243 ioctl(fd1, PERF_EVENT_IOC_ENABLE, 0); 244 ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0); 245 ioctl(fd3, PERF_EVENT_IOC_ENABLE, 0); 246 247 /* 248 * Kick off the test by trigering 'fd1' 249 * breakpoint. 250 */ 251 test_function(); 252 253 ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0); 254 ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0); 255 ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0); 256 257 count1 = bp_count(fd1); 258 count2 = bp_count(fd2); 259 count3 = bp_count(fd3); 260 261 close(fd1); 262 close(fd2); 263 close(fd3); 264 265 pr_debug("count1 %lld, count2 %lld, count3 %lld, overflow %d, overflows_2 %d\n", 266 count1, count2, count3, overflows, overflows_2); 267 268 if (count1 != 1) { 269 if (count1 == 11) 270 pr_debug("failed: RF EFLAG recursion issue detected\n"); 271 else 272 pr_debug("failed: wrong count for bp1%lld\n", count1); 273 } 274 275 if (overflows != 3) 276 pr_debug("failed: wrong overflow hit\n"); 277 278 if (overflows_2 != 3) 279 pr_debug("failed: wrong overflow_2 hit\n"); 280 281 if (count2 != 3) 282 pr_debug("failed: wrong count for bp2\n"); 283 284 if (count3 != 2) 285 pr_debug("failed: wrong count for bp3\n"); 286 287 return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ? 288 TEST_OK : TEST_FAIL; 289 } 290 291 bool test__bp_signal_is_supported(void) 292 { 293 /* 294 * The powerpc so far does not have support to even create 295 * instruction breakpoint using the perf event interface. 296 * Once it's there we can release this. 297 */ 298 #ifdef __powerpc__ 299 return false; 300 #else 301 return true; 302 #endif 303 } 304