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