1
2
3
4
5
6
7
8
9
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
30static int fd1;
31static int fd2;
32static int fd3;
33static int overflows;
34static int overflows_2;
35
36volatile long the_var;
37
38
39
40
41
42
43#if defined (__x86_64__)
44extern void __test_function(volatile long *ptr);
45asm (
46 ".globl __test_function\n"
47 "__test_function:\n"
48 "incq (%rdi)\n"
49 "ret\n");
50#elif defined (__aarch64__)
51extern void __test_function(volatile long *ptr);
52asm (
53 ".globl __test_function\n"
54 "__test_function:\n"
55 "str x30, [x0]\n"
56 "ret\n");
57
58#else
59static void __test_function(volatile long *ptr)
60{
61 *ptr = 0x1234;
62}
63#endif
64
65static noinline int test_function(void)
66{
67 __test_function(&the_var);
68 the_var++;
69 return time(NULL);
70}
71
72static 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
84static 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
93
94
95
96
97
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
105static 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
143static int bp_event(void *addr, int sig)
144{
145 return __event(true, addr, sig);
146}
147
148static int wp_event(void *addr, int sig)
149{
150 return __event(false, addr, sig);
151}
152
153static 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
167int test__bp_signal(int subtest __maybe_unused)
168{
169 struct sigaction sa;
170 long long count1, count2, count3;
171
172
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
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 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
249
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
291bool test__bp_signal_is_supported(void)
292{
293
294
295
296
297
298#ifdef __powerpc__
299 return false;
300#else
301 return true;
302#endif
303}
304