1
2
3
4
5
6
7
8
9
10
11
12#define __SANE_USERSPACE_TYPES__
13
14#include <stdlib.h>
15#include <stdio.h>
16#include <unistd.h>
17#include <string.h>
18#include <sys/ioctl.h>
19#include <time.h>
20#include <fcntl.h>
21#include <signal.h>
22#include <sys/mman.h>
23#include <linux/compiler.h>
24#include <linux/hw_breakpoint.h>
25
26#include "tests.h"
27#include "debug.h"
28#include "perf.h"
29#include "cloexec.h"
30
31static int fd1;
32static int fd2;
33static int fd3;
34static int overflows;
35static int overflows_2;
36
37volatile long the_var;
38
39
40
41
42
43
44#if defined (__x86_64__)
45extern void __test_function(volatile long *ptr);
46asm (
47 ".globl __test_function\n"
48 "__test_function:\n"
49 "incq (%rdi)\n"
50 "ret\n");
51#elif defined (__aarch64__)
52extern void __test_function(volatile long *ptr);
53asm (
54 ".globl __test_function\n"
55 "__test_function:\n"
56 "str x30, [x0]\n"
57 "ret\n");
58
59#else
60static void __test_function(volatile long *ptr)
61{
62 *ptr = 0x1234;
63}
64#endif
65
66static noinline int test_function(void)
67{
68 __test_function(&the_var);
69 the_var++;
70 return time(NULL);
71}
72
73static void sig_handler_2(int signum __maybe_unused,
74 siginfo_t *oh __maybe_unused,
75 void *uc __maybe_unused)
76{
77 overflows_2++;
78 if (overflows_2 > 10) {
79 ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
80 ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
81 ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
82 }
83}
84
85static void sig_handler(int signum __maybe_unused,
86 siginfo_t *oh __maybe_unused,
87 void *uc __maybe_unused)
88{
89 overflows++;
90
91 if (overflows > 10) {
92
93
94
95
96
97
98
99
100 ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
101 ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
102 ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
103 }
104}
105
106static int __event(bool is_x, void *addr, int sig)
107{
108 struct perf_event_attr pe;
109 int fd;
110
111 memset(&pe, 0, sizeof(struct perf_event_attr));
112 pe.type = PERF_TYPE_BREAKPOINT;
113 pe.size = sizeof(struct perf_event_attr);
114
115 pe.config = 0;
116 pe.bp_type = is_x ? HW_BREAKPOINT_X : HW_BREAKPOINT_W;
117 pe.bp_addr = (unsigned long) addr;
118 pe.bp_len = sizeof(long);
119
120 pe.sample_period = 1;
121 pe.sample_type = PERF_SAMPLE_IP;
122 pe.wakeup_events = 1;
123
124 pe.disabled = 1;
125 pe.exclude_kernel = 1;
126 pe.exclude_hv = 1;
127
128 fd = sys_perf_event_open(&pe, 0, -1, -1,
129 perf_event_open_cloexec_flag());
130 if (fd < 0) {
131 pr_debug("failed opening event %llx\n", pe.config);
132 return TEST_FAIL;
133 }
134
135 fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
136 fcntl(fd, F_SETSIG, sig);
137 fcntl(fd, F_SETOWN, getpid());
138
139 ioctl(fd, PERF_EVENT_IOC_RESET, 0);
140
141 return fd;
142}
143
144static int bp_event(void *addr, int sig)
145{
146 return __event(true, addr, sig);
147}
148
149static int wp_event(void *addr, int sig)
150{
151 return __event(false, addr, sig);
152}
153
154static long long bp_count(int fd)
155{
156 long long count;
157 int ret;
158
159 ret = read(fd, &count, sizeof(long long));
160 if (ret != sizeof(long long)) {
161 pr_debug("failed to read: %d\n", ret);
162 return TEST_FAIL;
163 }
164
165 return count;
166}
167
168int test__bp_signal(struct test *test __maybe_unused, int subtest __maybe_unused)
169{
170 struct sigaction sa;
171 long long count1, count2, count3;
172
173
174 memset(&sa, 0, sizeof(struct sigaction));
175 sa.sa_sigaction = (void *) sig_handler;
176 sa.sa_flags = SA_SIGINFO;
177
178 if (sigaction(SIGIO, &sa, NULL) < 0) {
179 pr_debug("failed setting up signal handler\n");
180 return TEST_FAIL;
181 }
182
183 sa.sa_sigaction = (void *) sig_handler_2;
184 if (sigaction(SIGUSR1, &sa, NULL) < 0) {
185 pr_debug("failed setting up signal handler 2\n");
186 return TEST_FAIL;
187 }
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240 fd1 = bp_event(__test_function, SIGIO);
241 fd2 = bp_event(sig_handler, SIGUSR1);
242 fd3 = wp_event((void *)&the_var, SIGIO);
243
244 ioctl(fd1, PERF_EVENT_IOC_ENABLE, 0);
245 ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0);
246 ioctl(fd3, PERF_EVENT_IOC_ENABLE, 0);
247
248
249
250
251
252 test_function();
253
254 ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
255 ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
256 ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
257
258 count1 = bp_count(fd1);
259 count2 = bp_count(fd2);
260 count3 = bp_count(fd3);
261
262 close(fd1);
263 close(fd2);
264 close(fd3);
265
266 pr_debug("count1 %lld, count2 %lld, count3 %lld, overflow %d, overflows_2 %d\n",
267 count1, count2, count3, overflows, overflows_2);
268
269 if (count1 != 1) {
270 if (count1 == 11)
271 pr_debug("failed: RF EFLAG recursion issue detected\n");
272 else
273 pr_debug("failed: wrong count for bp1%lld\n", count1);
274 }
275
276 if (overflows != 3)
277 pr_debug("failed: wrong overflow hit\n");
278
279 if (overflows_2 != 3)
280 pr_debug("failed: wrong overflow_2 hit\n");
281
282 if (count2 != 3)
283 pr_debug("failed: wrong count for bp2\n");
284
285 if (count3 != 2)
286 pr_debug("failed: wrong count for bp3\n");
287
288 return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ?
289 TEST_OK : TEST_FAIL;
290}
291
292bool test__bp_signal_is_supported(void)
293{
294
295
296
297
298
299#if defined(__powerpc__) || defined(__s390x__)
300 return false;
301#else
302 return true;
303#endif
304}
305