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 "event.h"
29#include "perf-sys.h"
30#include "cloexec.h"
31
32static int fd1;
33static int fd2;
34static int fd3;
35static int overflows;
36static int overflows_2;
37
38volatile long the_var;
39
40
41
42
43
44
45#if defined (__x86_64__)
46extern void __test_function(volatile long *ptr);
47asm (
48 ".pushsection .text;"
49 ".globl __test_function\n"
50 ".type __test_function, @function;"
51 "__test_function:\n"
52 "incq (%rdi)\n"
53 "ret\n"
54 ".popsection\n");
55#else
56static void __test_function(volatile long *ptr)
57{
58 *ptr = 0x1234;
59}
60#endif
61
62static noinline int test_function(void)
63{
64 __test_function(&the_var);
65 the_var++;
66 return time(NULL);
67}
68
69static void sig_handler_2(int signum __maybe_unused,
70 siginfo_t *oh __maybe_unused,
71 void *uc __maybe_unused)
72{
73 overflows_2++;
74 if (overflows_2 > 10) {
75 ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
76 ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
77 ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
78 }
79}
80
81static void sig_handler(int signum __maybe_unused,
82 siginfo_t *oh __maybe_unused,
83 void *uc __maybe_unused)
84{
85 overflows++;
86
87 if (overflows > 10) {
88
89
90
91
92
93
94
95
96 ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
97 ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
98 ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
99 }
100}
101
102static int __event(bool is_x, void *addr, int sig)
103{
104 struct perf_event_attr pe;
105 int fd;
106
107 memset(&pe, 0, sizeof(struct perf_event_attr));
108 pe.type = PERF_TYPE_BREAKPOINT;
109 pe.size = sizeof(struct perf_event_attr);
110
111 pe.config = 0;
112 pe.bp_type = is_x ? HW_BREAKPOINT_X : HW_BREAKPOINT_W;
113 pe.bp_addr = (unsigned long) addr;
114 pe.bp_len = sizeof(long);
115
116 pe.sample_period = 1;
117 pe.sample_type = PERF_SAMPLE_IP;
118 pe.wakeup_events = 1;
119
120 pe.disabled = 1;
121 pe.exclude_kernel = 1;
122 pe.exclude_hv = 1;
123
124 fd = sys_perf_event_open(&pe, 0, -1, -1,
125 perf_event_open_cloexec_flag());
126 if (fd < 0) {
127 pr_debug("failed opening event %llx\n", pe.config);
128 return TEST_FAIL;
129 }
130
131 fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
132 fcntl(fd, F_SETSIG, sig);
133 fcntl(fd, F_SETOWN, getpid());
134
135 ioctl(fd, PERF_EVENT_IOC_RESET, 0);
136
137 return fd;
138}
139
140static int bp_event(void *addr, int sig)
141{
142 return __event(true, addr, sig);
143}
144
145static int wp_event(void *addr, int sig)
146{
147 return __event(false, addr, sig);
148}
149
150static long long bp_count(int fd)
151{
152 long long count;
153 int ret;
154
155 ret = read(fd, &count, sizeof(long long));
156 if (ret != sizeof(long long)) {
157 pr_debug("failed to read: %d\n", ret);
158 return TEST_FAIL;
159 }
160
161 return count;
162}
163
164int test__bp_signal(struct test *test __maybe_unused, int subtest __maybe_unused)
165{
166 struct sigaction sa;
167 long long count1, count2, count3;
168
169
170 memset(&sa, 0, sizeof(struct sigaction));
171 sa.sa_sigaction = (void *) sig_handler;
172 sa.sa_flags = SA_SIGINFO;
173
174 if (sigaction(SIGIO, &sa, NULL) < 0) {
175 pr_debug("failed setting up signal handler\n");
176 return TEST_FAIL;
177 }
178
179 sa.sa_sigaction = (void *) sig_handler_2;
180 if (sigaction(SIGUSR1, &sa, NULL) < 0) {
181 pr_debug("failed setting up signal handler 2\n");
182 return TEST_FAIL;
183 }
184
185
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 fd1 = bp_event(__test_function, SIGIO);
237 fd2 = bp_event(sig_handler, SIGUSR1);
238 fd3 = wp_event((void *)&the_var, SIGIO);
239
240 ioctl(fd1, PERF_EVENT_IOC_ENABLE, 0);
241 ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0);
242 ioctl(fd3, PERF_EVENT_IOC_ENABLE, 0);
243
244
245
246
247
248 test_function();
249
250 ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
251 ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
252 ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
253
254 count1 = bp_count(fd1);
255 count2 = bp_count(fd2);
256 count3 = bp_count(fd3);
257
258 close(fd1);
259 close(fd2);
260 close(fd3);
261
262 pr_debug("count1 %lld, count2 %lld, count3 %lld, overflow %d, overflows_2 %d\n",
263 count1, count2, count3, overflows, overflows_2);
264
265 if (count1 != 1) {
266 if (count1 == 11)
267 pr_debug("failed: RF EFLAG recursion issue detected\n");
268 else
269 pr_debug("failed: wrong count for bp1: %lld, expected 1\n", count1);
270 }
271
272 if (overflows != 3)
273 pr_debug("failed: wrong overflow (%d) hit, expected 3\n", overflows);
274
275 if (overflows_2 != 3)
276 pr_debug("failed: wrong overflow_2 (%d) hit, expected 3\n", overflows_2);
277
278 if (count2 != 3)
279 pr_debug("failed: wrong count for bp2 (%lld), expected 3\n", count2);
280
281 if (count3 != 2)
282 pr_debug("failed: wrong count for bp3 (%lld), expected 2\n", count3);
283
284 return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ?
285 TEST_OK : TEST_FAIL;
286}
287
288bool test__bp_signal_is_supported(void)
289{
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307#if defined(__powerpc__) || defined(__s390x__) || defined(__arm__) || \
308 defined(__aarch64__)
309 return false;
310#else
311 return true;
312#endif
313}
314