spnego: add missing OID to oid registry
[sfrench/cifs-2.6.git] / tools / testing / selftests / powerpc / ptrace / perf-hwbreak.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * perf events self profiling example test case for hw breakpoints.
4  *
5  * This tests perf PERF_TYPE_BREAKPOINT parameters
6  * 1) tests all variants of the break on read/write flags
7  * 2) tests exclude_user == 0 and 1
8  * 3) test array matches (if DAWR is supported))
9  * 4) test different numbers of breakpoints matches
10  *
11  * Configure this breakpoint, then read and write the data a number of
12  * times. Then check the output count from perf is as expected.
13  *
14  * Based on:
15  *   http://ozlabs.org/~anton/junkcode/perf_events_example1.c
16  *
17  * Copyright (C) 2018 Michael Neuling, IBM Corporation.
18  */
19
20 #define _GNU_SOURCE
21
22 #include <unistd.h>
23 #include <assert.h>
24 #include <sched.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <signal.h>
28 #include <string.h>
29 #include <sys/ioctl.h>
30 #include <sys/wait.h>
31 #include <sys/ptrace.h>
32 #include <sys/resource.h>
33 #include <sys/sysinfo.h>
34 #include <asm/ptrace.h>
35 #include <elf.h>
36 #include <pthread.h>
37 #include <sys/syscall.h>
38 #include <linux/perf_event.h>
39 #include <linux/hw_breakpoint.h>
40 #include "utils.h"
41
42 #ifndef PPC_DEBUG_FEATURE_DATA_BP_ARCH_31
43 #define PPC_DEBUG_FEATURE_DATA_BP_ARCH_31       0x20
44 #endif
45
46 #define MAX_LOOPS 10000
47
48 #define DAWR_LENGTH_MAX ((0x3f + 1) * 8)
49
50 int nprocs;
51
52 static volatile int a = 10;
53 static volatile int b = 10;
54 static volatile char c[512 + 8] __attribute__((aligned(512)));
55
56 static void perf_event_attr_set(struct perf_event_attr *attr,
57                                 __u32 type, __u64 addr, __u64 len,
58                                 bool exclude_user)
59 {
60         memset(attr, 0, sizeof(struct perf_event_attr));
61         attr->type           = PERF_TYPE_BREAKPOINT;
62         attr->size           = sizeof(struct perf_event_attr);
63         attr->bp_type        = type;
64         attr->bp_addr        = addr;
65         attr->bp_len         = len;
66         attr->exclude_kernel = 1;
67         attr->exclude_hv     = 1;
68         attr->exclude_guest  = 1;
69         attr->exclude_user   = exclude_user;
70         attr->disabled       = 1;
71 }
72
73 static int
74 perf_process_event_open_exclude_user(__u32 type, __u64 addr, __u64 len, bool exclude_user)
75 {
76         struct perf_event_attr attr;
77
78         perf_event_attr_set(&attr, type, addr, len, exclude_user);
79         return syscall(__NR_perf_event_open, &attr, getpid(), -1, -1, 0);
80 }
81
82 static int perf_process_event_open(__u32 type, __u64 addr, __u64 len)
83 {
84         struct perf_event_attr attr;
85
86         perf_event_attr_set(&attr, type, addr, len, 0);
87         return syscall(__NR_perf_event_open, &attr, getpid(), -1, -1, 0);
88 }
89
90 static int perf_cpu_event_open(long cpu, __u32 type, __u64 addr, __u64 len)
91 {
92         struct perf_event_attr attr;
93
94         perf_event_attr_set(&attr, type, addr, len, 0);
95         return syscall(__NR_perf_event_open, &attr, -1, cpu, -1, 0);
96 }
97
98 static void close_fds(int *fd, int n)
99 {
100         int i;
101
102         for (i = 0; i < n; i++)
103                 close(fd[i]);
104 }
105
106 static unsigned long read_fds(int *fd, int n)
107 {
108         int i;
109         unsigned long c = 0;
110         unsigned long count = 0;
111         size_t res;
112
113         for (i = 0; i < n; i++) {
114                 res = read(fd[i], &c, sizeof(c));
115                 assert(res == sizeof(unsigned long long));
116                 count += c;
117         }
118         return count;
119 }
120
121 static void reset_fds(int *fd, int n)
122 {
123         int i;
124
125         for (i = 0; i < n; i++)
126                 ioctl(fd[i], PERF_EVENT_IOC_RESET);
127 }
128
129 static void enable_fds(int *fd, int n)
130 {
131         int i;
132
133         for (i = 0; i < n; i++)
134                 ioctl(fd[i], PERF_EVENT_IOC_ENABLE);
135 }
136
137 static void disable_fds(int *fd, int n)
138 {
139         int i;
140
141         for (i = 0; i < n; i++)
142                 ioctl(fd[i], PERF_EVENT_IOC_DISABLE);
143 }
144
145 static int perf_systemwide_event_open(int *fd, __u32 type, __u64 addr, __u64 len)
146 {
147         int i, ncpus, cpu, ret = 0;
148         struct rlimit rlim;
149         cpu_set_t *mask;
150         size_t size;
151
152         if (getrlimit(RLIMIT_NOFILE, &rlim)) {
153                 perror("getrlimit");
154                 return -1;
155         }
156         rlim.rlim_cur = 65536;
157         if (setrlimit(RLIMIT_NOFILE, &rlim)) {
158                 perror("setrlimit");
159                 return -1;
160         }
161
162         ncpus = get_nprocs_conf();
163         size = CPU_ALLOC_SIZE(ncpus);
164         mask = CPU_ALLOC(ncpus);
165         if (!mask) {
166                 perror("malloc");
167                 return -1;
168         }
169
170         CPU_ZERO_S(size, mask);
171
172         if (sched_getaffinity(0, size, mask)) {
173                 perror("sched_getaffinity");
174                 ret = -1;
175                 goto done;
176         }
177
178         for (i = 0, cpu = 0; i < nprocs && cpu < ncpus; cpu++) {
179                 if (!CPU_ISSET_S(cpu, size, mask))
180                         continue;
181                 fd[i] = perf_cpu_event_open(cpu, type, addr, len);
182                 if (fd[i] < 0) {
183                         perror("perf_systemwide_event_open");
184                         close_fds(fd, i);
185                         ret = fd[i];
186                         goto done;
187                 }
188                 i++;
189         }
190
191         if (i < nprocs) {
192                 printf("Error: Number of online cpus reduced since start of test: %d < %d\n", i, nprocs);
193                 close_fds(fd, i);
194                 ret = -1;
195         }
196
197 done:
198         CPU_FREE(mask);
199         return ret;
200 }
201
202 static inline bool breakpoint_test(int len)
203 {
204         int fd;
205
206         /* bp_addr can point anywhere but needs to be aligned */
207         fd = perf_process_event_open(HW_BREAKPOINT_R, (__u64)(&fd) & 0xfffffffffffff800, len);
208         if (fd < 0)
209                 return false;
210         close(fd);
211         return true;
212 }
213
214 static inline bool perf_breakpoint_supported(void)
215 {
216         return breakpoint_test(4);
217 }
218
219 static inline bool dawr_supported(void)
220 {
221         return breakpoint_test(DAWR_LENGTH_MAX);
222 }
223
224 static int runtestsingle(int readwriteflag, int exclude_user, int arraytest)
225 {
226         int i,j;
227         size_t res;
228         unsigned long long breaks, needed;
229         int readint;
230         int readintarraybig[2*DAWR_LENGTH_MAX/sizeof(int)];
231         int *readintalign;
232         volatile int *ptr;
233         int break_fd;
234         int loop_num = MAX_LOOPS - (rand() % 100); /* provide some variability */
235         volatile int *k;
236         __u64 len;
237
238         /* align to 0x400 boundary as required by DAWR */
239         readintalign = (int *)(((unsigned long)readintarraybig + 0x7ff) &
240                                0xfffffffffffff800);
241
242         ptr = &readint;
243         if (arraytest)
244                 ptr = &readintalign[0];
245
246         len = arraytest ? DAWR_LENGTH_MAX : sizeof(int);
247         break_fd = perf_process_event_open_exclude_user(readwriteflag, (__u64)ptr,
248                                                         len, exclude_user);
249         if (break_fd < 0) {
250                 perror("perf_process_event_open_exclude_user");
251                 exit(1);
252         }
253
254         /* start counters */
255         ioctl(break_fd, PERF_EVENT_IOC_ENABLE);
256
257         /* Test a bunch of reads and writes */
258         k = &readint;
259         for (i = 0; i < loop_num; i++) {
260                 if (arraytest)
261                         k = &(readintalign[i % (DAWR_LENGTH_MAX/sizeof(int))]);
262
263                 j = *k;
264                 *k = j;
265         }
266
267         /* stop counters */
268         ioctl(break_fd, PERF_EVENT_IOC_DISABLE);
269
270         /* read and check counters */
271         res = read(break_fd, &breaks, sizeof(unsigned long long));
272         assert(res == sizeof(unsigned long long));
273         /* we read and write each loop, so subtract the ones we are counting */
274         needed = 0;
275         if (readwriteflag & HW_BREAKPOINT_R)
276                 needed += loop_num;
277         if (readwriteflag & HW_BREAKPOINT_W)
278                 needed += loop_num;
279         needed = needed * (1 - exclude_user);
280         printf("TESTED: addr:0x%lx brks:% 8lld loops:% 8i rw:%i !user:%i array:%i\n",
281                (unsigned long int)ptr, breaks, loop_num, readwriteflag, exclude_user, arraytest);
282         if (breaks != needed) {
283                 printf("FAILED: 0x%lx brks:%lld needed:%lli %i %i %i\n\n",
284                        (unsigned long int)ptr, breaks, needed, loop_num, readwriteflag, exclude_user);
285                 return 1;
286         }
287         close(break_fd);
288
289         return 0;
290 }
291
292 static int runtest_dar_outside(void)
293 {
294         void *target;
295         volatile __u16 temp16;
296         volatile __u64 temp64;
297         int break_fd;
298         unsigned long long breaks;
299         int fail = 0;
300         size_t res;
301
302         target = malloc(8);
303         if (!target) {
304                 perror("malloc failed");
305                 exit(EXIT_FAILURE);
306         }
307
308         /* watch middle half of target array */
309         break_fd = perf_process_event_open(HW_BREAKPOINT_RW, (__u64)(target + 2), 4);
310         if (break_fd < 0) {
311                 free(target);
312                 perror("perf_process_event_open");
313                 exit(EXIT_FAILURE);
314         }
315
316         /* Shouldn't hit. */
317         ioctl(break_fd, PERF_EVENT_IOC_RESET);
318         ioctl(break_fd, PERF_EVENT_IOC_ENABLE);
319         temp16 = *((__u16 *)target);
320         *((__u16 *)target) = temp16;
321         ioctl(break_fd, PERF_EVENT_IOC_DISABLE);
322         res = read(break_fd, &breaks, sizeof(unsigned long long));
323         assert(res == sizeof(unsigned long long));
324         if (breaks == 0) {
325                 printf("TESTED: No overlap\n");
326         } else {
327                 printf("FAILED: No overlap: %lld != 0\n", breaks);
328                 fail = 1;
329         }
330
331         /* Hit */
332         ioctl(break_fd, PERF_EVENT_IOC_RESET);
333         ioctl(break_fd, PERF_EVENT_IOC_ENABLE);
334         temp16 = *((__u16 *)(target + 1));
335         *((__u16 *)(target + 1)) = temp16;
336         ioctl(break_fd, PERF_EVENT_IOC_DISABLE);
337         res = read(break_fd, &breaks, sizeof(unsigned long long));
338         assert(res == sizeof(unsigned long long));
339         if (breaks == 2) {
340                 printf("TESTED: Partial overlap\n");
341         } else {
342                 printf("FAILED: Partial overlap: %lld != 2\n", breaks);
343                 fail = 1;
344         }
345
346         /* Hit */
347         ioctl(break_fd, PERF_EVENT_IOC_RESET);
348         ioctl(break_fd, PERF_EVENT_IOC_ENABLE);
349         temp16 = *((__u16 *)(target + 5));
350         *((__u16 *)(target + 5)) = temp16;
351         ioctl(break_fd, PERF_EVENT_IOC_DISABLE);
352         res = read(break_fd, &breaks, sizeof(unsigned long long));
353         assert(res == sizeof(unsigned long long));
354         if (breaks == 2) {
355                 printf("TESTED: Partial overlap\n");
356         } else {
357                 printf("FAILED: Partial overlap: %lld != 2\n", breaks);
358                 fail = 1;
359         }
360
361         /* Shouldn't Hit */
362         ioctl(break_fd, PERF_EVENT_IOC_RESET);
363         ioctl(break_fd, PERF_EVENT_IOC_ENABLE);
364         temp16 = *((__u16 *)(target + 6));
365         *((__u16 *)(target + 6)) = temp16;
366         ioctl(break_fd, PERF_EVENT_IOC_DISABLE);
367         res = read(break_fd, &breaks, sizeof(unsigned long long));
368         assert(res == sizeof(unsigned long long));
369         if (breaks == 0) {
370                 printf("TESTED: No overlap\n");
371         } else {
372                 printf("FAILED: No overlap: %lld != 0\n", breaks);
373                 fail = 1;
374         }
375
376         /* Hit */
377         ioctl(break_fd, PERF_EVENT_IOC_RESET);
378         ioctl(break_fd, PERF_EVENT_IOC_ENABLE);
379         temp64 = *((__u64 *)target);
380         *((__u64 *)target) = temp64;
381         ioctl(break_fd, PERF_EVENT_IOC_DISABLE);
382         res = read(break_fd, &breaks, sizeof(unsigned long long));
383         assert(res == sizeof(unsigned long long));
384         if (breaks == 2) {
385                 printf("TESTED: Full overlap\n");
386         } else {
387                 printf("FAILED: Full overlap: %lld != 2\n", breaks);
388                 fail = 1;
389         }
390
391         free(target);
392         close(break_fd);
393         return fail;
394 }
395
396 static void multi_dawr_workload(void)
397 {
398         a += 10;
399         b += 10;
400         c[512 + 1] += 'a';
401 }
402
403 static int test_process_multi_diff_addr(void)
404 {
405         unsigned long long breaks1 = 0, breaks2 = 0;
406         int fd1, fd2;
407         char *desc = "Process specific, Two events, diff addr";
408         size_t res;
409
410         fd1 = perf_process_event_open(HW_BREAKPOINT_RW, (__u64)&a, (__u64)sizeof(a));
411         if (fd1 < 0) {
412                 perror("perf_process_event_open");
413                 exit(EXIT_FAILURE);
414         }
415
416         fd2 = perf_process_event_open(HW_BREAKPOINT_RW, (__u64)&b, (__u64)sizeof(b));
417         if (fd2 < 0) {
418                 close(fd1);
419                 perror("perf_process_event_open");
420                 exit(EXIT_FAILURE);
421         }
422
423         ioctl(fd1, PERF_EVENT_IOC_RESET);
424         ioctl(fd2, PERF_EVENT_IOC_RESET);
425         ioctl(fd1, PERF_EVENT_IOC_ENABLE);
426         ioctl(fd2, PERF_EVENT_IOC_ENABLE);
427         multi_dawr_workload();
428         ioctl(fd1, PERF_EVENT_IOC_DISABLE);
429         ioctl(fd2, PERF_EVENT_IOC_DISABLE);
430
431         res = read(fd1, &breaks1, sizeof(breaks1));
432         assert(res == sizeof(unsigned long long));
433         res = read(fd2, &breaks2, sizeof(breaks2));
434         assert(res == sizeof(unsigned long long));
435
436         close(fd1);
437         close(fd2);
438
439         if (breaks1 != 2 || breaks2 != 2) {
440                 printf("FAILED: %s: %lld != 2 || %lld != 2\n", desc, breaks1, breaks2);
441                 return 1;
442         }
443
444         printf("TESTED: %s\n", desc);
445         return 0;
446 }
447
448 static int test_process_multi_same_addr(void)
449 {
450         unsigned long long breaks1 = 0, breaks2 = 0;
451         int fd1, fd2;
452         char *desc = "Process specific, Two events, same addr";
453         size_t res;
454
455         fd1 = perf_process_event_open(HW_BREAKPOINT_RW, (__u64)&a, (__u64)sizeof(a));
456         if (fd1 < 0) {
457                 perror("perf_process_event_open");
458                 exit(EXIT_FAILURE);
459         }
460
461         fd2 = perf_process_event_open(HW_BREAKPOINT_RW, (__u64)&a, (__u64)sizeof(a));
462         if (fd2 < 0) {
463                 close(fd1);
464                 perror("perf_process_event_open");
465                 exit(EXIT_FAILURE);
466         }
467
468         ioctl(fd1, PERF_EVENT_IOC_RESET);
469         ioctl(fd2, PERF_EVENT_IOC_RESET);
470         ioctl(fd1, PERF_EVENT_IOC_ENABLE);
471         ioctl(fd2, PERF_EVENT_IOC_ENABLE);
472         multi_dawr_workload();
473         ioctl(fd1, PERF_EVENT_IOC_DISABLE);
474         ioctl(fd2, PERF_EVENT_IOC_DISABLE);
475
476         res = read(fd1, &breaks1, sizeof(breaks1));
477         assert(res == sizeof(unsigned long long));
478         res = read(fd2, &breaks2, sizeof(breaks2));
479         assert(res == sizeof(unsigned long long));
480
481         close(fd1);
482         close(fd2);
483
484         if (breaks1 != 2 || breaks2 != 2) {
485                 printf("FAILED: %s: %lld != 2 || %lld != 2\n", desc, breaks1, breaks2);
486                 return 1;
487         }
488
489         printf("TESTED: %s\n", desc);
490         return 0;
491 }
492
493 static int test_process_multi_diff_addr_ro_wo(void)
494 {
495         unsigned long long breaks1 = 0, breaks2 = 0;
496         int fd1, fd2;
497         char *desc = "Process specific, Two events, diff addr, one is RO, other is WO";
498         size_t res;
499
500         fd1 = perf_process_event_open(HW_BREAKPOINT_W, (__u64)&a, (__u64)sizeof(a));
501         if (fd1 < 0) {
502                 perror("perf_process_event_open");
503                 exit(EXIT_FAILURE);
504         }
505
506         fd2 = perf_process_event_open(HW_BREAKPOINT_R, (__u64)&b, (__u64)sizeof(b));
507         if (fd2 < 0) {
508                 close(fd1);
509                 perror("perf_process_event_open");
510                 exit(EXIT_FAILURE);
511         }
512
513         ioctl(fd1, PERF_EVENT_IOC_RESET);
514         ioctl(fd2, PERF_EVENT_IOC_RESET);
515         ioctl(fd1, PERF_EVENT_IOC_ENABLE);
516         ioctl(fd2, PERF_EVENT_IOC_ENABLE);
517         multi_dawr_workload();
518         ioctl(fd1, PERF_EVENT_IOC_DISABLE);
519         ioctl(fd2, PERF_EVENT_IOC_DISABLE);
520
521         res = read(fd1, &breaks1, sizeof(breaks1));
522         assert(res == sizeof(unsigned long long));
523         res = read(fd2, &breaks2, sizeof(breaks2));
524         assert(res == sizeof(unsigned long long));
525
526         close(fd1);
527         close(fd2);
528
529         if (breaks1 != 1 || breaks2 != 1) {
530                 printf("FAILED: %s: %lld != 1 || %lld != 1\n", desc, breaks1, breaks2);
531                 return 1;
532         }
533
534         printf("TESTED: %s\n", desc);
535         return 0;
536 }
537
538 static int test_process_multi_same_addr_ro_wo(void)
539 {
540         unsigned long long breaks1 = 0, breaks2 = 0;
541         int fd1, fd2;
542         char *desc = "Process specific, Two events, same addr, one is RO, other is WO";
543         size_t res;
544
545         fd1 = perf_process_event_open(HW_BREAKPOINT_R, (__u64)&a, (__u64)sizeof(a));
546         if (fd1 < 0) {
547                 perror("perf_process_event_open");
548                 exit(EXIT_FAILURE);
549         }
550
551         fd2 = perf_process_event_open(HW_BREAKPOINT_W, (__u64)&a, (__u64)sizeof(a));
552         if (fd2 < 0) {
553                 close(fd1);
554                 perror("perf_process_event_open");
555                 exit(EXIT_FAILURE);
556         }
557
558         ioctl(fd1, PERF_EVENT_IOC_RESET);
559         ioctl(fd2, PERF_EVENT_IOC_RESET);
560         ioctl(fd1, PERF_EVENT_IOC_ENABLE);
561         ioctl(fd2, PERF_EVENT_IOC_ENABLE);
562         multi_dawr_workload();
563         ioctl(fd1, PERF_EVENT_IOC_DISABLE);
564         ioctl(fd2, PERF_EVENT_IOC_DISABLE);
565
566         res = read(fd1, &breaks1, sizeof(breaks1));
567         assert(res == sizeof(unsigned long long));
568         res = read(fd2, &breaks2, sizeof(breaks2));
569         assert(res == sizeof(unsigned long long));
570
571         close(fd1);
572         close(fd2);
573
574         if (breaks1 != 1 || breaks2 != 1) {
575                 printf("FAILED: %s: %lld != 1 || %lld != 1\n", desc, breaks1, breaks2);
576                 return 1;
577         }
578
579         printf("TESTED: %s\n", desc);
580         return 0;
581 }
582
583 static int test_syswide_multi_diff_addr(void)
584 {
585         unsigned long long breaks1 = 0, breaks2 = 0;
586         int *fd1 = malloc(nprocs * sizeof(int));
587         int *fd2 = malloc(nprocs * sizeof(int));
588         char *desc = "Systemwide, Two events, diff addr";
589         int ret;
590
591         ret = perf_systemwide_event_open(fd1, HW_BREAKPOINT_RW, (__u64)&a, (__u64)sizeof(a));
592         if (ret)
593                 exit(EXIT_FAILURE);
594
595         ret = perf_systemwide_event_open(fd2, HW_BREAKPOINT_RW, (__u64)&b, (__u64)sizeof(b));
596         if (ret) {
597                 close_fds(fd1, nprocs);
598                 exit(EXIT_FAILURE);
599         }
600
601         reset_fds(fd1, nprocs);
602         reset_fds(fd2, nprocs);
603         enable_fds(fd1, nprocs);
604         enable_fds(fd2, nprocs);
605         multi_dawr_workload();
606         disable_fds(fd1, nprocs);
607         disable_fds(fd2, nprocs);
608
609         breaks1 = read_fds(fd1, nprocs);
610         breaks2 = read_fds(fd2, nprocs);
611
612         close_fds(fd1, nprocs);
613         close_fds(fd2, nprocs);
614
615         free(fd1);
616         free(fd2);
617
618         if (breaks1 != 2 || breaks2 != 2) {
619                 printf("FAILED: %s: %lld != 2 || %lld != 2\n", desc, breaks1, breaks2);
620                 return 1;
621         }
622
623         printf("TESTED: %s\n", desc);
624         return 0;
625 }
626
627 static int test_syswide_multi_same_addr(void)
628 {
629         unsigned long long breaks1 = 0, breaks2 = 0;
630         int *fd1 = malloc(nprocs * sizeof(int));
631         int *fd2 = malloc(nprocs * sizeof(int));
632         char *desc = "Systemwide, Two events, same addr";
633         int ret;
634
635         ret = perf_systemwide_event_open(fd1, HW_BREAKPOINT_RW, (__u64)&a, (__u64)sizeof(a));
636         if (ret)
637                 exit(EXIT_FAILURE);
638
639         ret = perf_systemwide_event_open(fd2, HW_BREAKPOINT_RW, (__u64)&a, (__u64)sizeof(a));
640         if (ret) {
641                 close_fds(fd1, nprocs);
642                 exit(EXIT_FAILURE);
643         }
644
645         reset_fds(fd1, nprocs);
646         reset_fds(fd2, nprocs);
647         enable_fds(fd1, nprocs);
648         enable_fds(fd2, nprocs);
649         multi_dawr_workload();
650         disable_fds(fd1, nprocs);
651         disable_fds(fd2, nprocs);
652
653         breaks1 = read_fds(fd1, nprocs);
654         breaks2 = read_fds(fd2, nprocs);
655
656         close_fds(fd1, nprocs);
657         close_fds(fd2, nprocs);
658
659         free(fd1);
660         free(fd2);
661
662         if (breaks1 != 2 || breaks2 != 2) {
663                 printf("FAILED: %s: %lld != 2 || %lld != 2\n", desc, breaks1, breaks2);
664                 return 1;
665         }
666
667         printf("TESTED: %s\n", desc);
668         return 0;
669 }
670
671 static int test_syswide_multi_diff_addr_ro_wo(void)
672 {
673         unsigned long long breaks1 = 0, breaks2 = 0;
674         int *fd1 = malloc(nprocs * sizeof(int));
675         int *fd2 = malloc(nprocs * sizeof(int));
676         char *desc = "Systemwide, Two events, diff addr, one is RO, other is WO";
677         int ret;
678
679         ret = perf_systemwide_event_open(fd1, HW_BREAKPOINT_W, (__u64)&a, (__u64)sizeof(a));
680         if (ret)
681                 exit(EXIT_FAILURE);
682
683         ret = perf_systemwide_event_open(fd2, HW_BREAKPOINT_R, (__u64)&b, (__u64)sizeof(b));
684         if (ret) {
685                 close_fds(fd1, nprocs);
686                 exit(EXIT_FAILURE);
687         }
688
689         reset_fds(fd1, nprocs);
690         reset_fds(fd2, nprocs);
691         enable_fds(fd1, nprocs);
692         enable_fds(fd2, nprocs);
693         multi_dawr_workload();
694         disable_fds(fd1, nprocs);
695         disable_fds(fd2, nprocs);
696
697         breaks1 = read_fds(fd1, nprocs);
698         breaks2 = read_fds(fd2, nprocs);
699
700         close_fds(fd1, nprocs);
701         close_fds(fd2, nprocs);
702
703         free(fd1);
704         free(fd2);
705
706         if (breaks1 != 1 || breaks2 != 1) {
707                 printf("FAILED: %s: %lld != 1 || %lld != 1\n", desc, breaks1, breaks2);
708                 return 1;
709         }
710
711         printf("TESTED: %s\n", desc);
712         return 0;
713 }
714
715 static int test_syswide_multi_same_addr_ro_wo(void)
716 {
717         unsigned long long breaks1 = 0, breaks2 = 0;
718         int *fd1 = malloc(nprocs * sizeof(int));
719         int *fd2 = malloc(nprocs * sizeof(int));
720         char *desc = "Systemwide, Two events, same addr, one is RO, other is WO";
721         int ret;
722
723         ret = perf_systemwide_event_open(fd1, HW_BREAKPOINT_W, (__u64)&a, (__u64)sizeof(a));
724         if (ret)
725                 exit(EXIT_FAILURE);
726
727         ret = perf_systemwide_event_open(fd2, HW_BREAKPOINT_R, (__u64)&a, (__u64)sizeof(a));
728         if (ret) {
729                 close_fds(fd1, nprocs);
730                 exit(EXIT_FAILURE);
731         }
732
733         reset_fds(fd1, nprocs);
734         reset_fds(fd2, nprocs);
735         enable_fds(fd1, nprocs);
736         enable_fds(fd2, nprocs);
737         multi_dawr_workload();
738         disable_fds(fd1, nprocs);
739         disable_fds(fd2, nprocs);
740
741         breaks1 = read_fds(fd1, nprocs);
742         breaks2 = read_fds(fd2, nprocs);
743
744         close_fds(fd1, nprocs);
745         close_fds(fd2, nprocs);
746
747         free(fd1);
748         free(fd2);
749
750         if (breaks1 != 1 || breaks2 != 1) {
751                 printf("FAILED: %s: %lld != 1 || %lld != 1\n", desc, breaks1, breaks2);
752                 return 1;
753         }
754
755         printf("TESTED: %s\n", desc);
756         return 0;
757 }
758
759 static int runtest_multi_dawr(void)
760 {
761         int ret = 0;
762
763         ret |= test_process_multi_diff_addr();
764         ret |= test_process_multi_same_addr();
765         ret |= test_process_multi_diff_addr_ro_wo();
766         ret |= test_process_multi_same_addr_ro_wo();
767         ret |= test_syswide_multi_diff_addr();
768         ret |= test_syswide_multi_same_addr();
769         ret |= test_syswide_multi_diff_addr_ro_wo();
770         ret |= test_syswide_multi_same_addr_ro_wo();
771
772         return ret;
773 }
774
775 static int runtest_unaligned_512bytes(void)
776 {
777         unsigned long long breaks = 0;
778         int fd;
779         char *desc = "Process specific, 512 bytes, unaligned";
780         __u64 addr = (__u64)&c + 8;
781         size_t res;
782
783         fd = perf_process_event_open(HW_BREAKPOINT_RW, addr, 512);
784         if (fd < 0) {
785                 perror("perf_process_event_open");
786                 exit(EXIT_FAILURE);
787         }
788
789         ioctl(fd, PERF_EVENT_IOC_RESET);
790         ioctl(fd, PERF_EVENT_IOC_ENABLE);
791         multi_dawr_workload();
792         ioctl(fd, PERF_EVENT_IOC_DISABLE);
793
794         res = read(fd, &breaks, sizeof(breaks));
795         assert(res == sizeof(unsigned long long));
796
797         close(fd);
798
799         if (breaks != 2) {
800                 printf("FAILED: %s: %lld != 2\n", desc, breaks);
801                 return 1;
802         }
803
804         printf("TESTED: %s\n", desc);
805         return 0;
806 }
807
808 /* There is no perf api to find number of available watchpoints. Use ptrace. */
809 static int get_nr_wps(bool *arch_31)
810 {
811         struct ppc_debug_info dbginfo;
812         int child_pid;
813
814         child_pid = fork();
815         if (!child_pid) {
816                 int ret = ptrace(PTRACE_TRACEME, 0, NULL, 0);
817                 if (ret) {
818                         perror("PTRACE_TRACEME failed\n");
819                         exit(EXIT_FAILURE);
820                 }
821                 kill(getpid(), SIGUSR1);
822
823                 sleep(1);
824                 exit(EXIT_SUCCESS);
825         }
826
827         wait(NULL);
828         if (ptrace(PPC_PTRACE_GETHWDBGINFO, child_pid, NULL, &dbginfo)) {
829                 perror("Can't get breakpoint info");
830                 exit(EXIT_FAILURE);
831         }
832
833         *arch_31 = !!(dbginfo.features & PPC_DEBUG_FEATURE_DATA_BP_ARCH_31);
834         return dbginfo.num_data_bps;
835 }
836
837 static int runtest(void)
838 {
839         int rwflag;
840         int exclude_user;
841         int ret;
842         bool dawr = dawr_supported();
843         bool arch_31 = false;
844         int nr_wps = get_nr_wps(&arch_31);
845
846         /*
847          * perf defines rwflag as two bits read and write and at least
848          * one must be set.  So range 1-3.
849          */
850         for (rwflag = 1 ; rwflag < 4; rwflag++) {
851                 for (exclude_user = 0 ; exclude_user < 2; exclude_user++) {
852                         ret = runtestsingle(rwflag, exclude_user, 0);
853                         if (ret)
854                                 return ret;
855
856                         /* if we have the dawr, we can do an array test */
857                         if (!dawr)
858                                 continue;
859                         ret = runtestsingle(rwflag, exclude_user, 1);
860                         if (ret)
861                                 return ret;
862                 }
863         }
864
865         ret = runtest_dar_outside();
866         if (ret)
867                 return ret;
868
869         if (dawr && nr_wps > 1) {
870                 nprocs = get_nprocs();
871                 ret = runtest_multi_dawr();
872                 if (ret)
873                         return ret;
874         }
875
876         if (dawr && arch_31)
877                 ret = runtest_unaligned_512bytes();
878
879         return ret;
880 }
881
882
883 static int perf_hwbreak(void)
884 {
885         srand ( time(NULL) );
886
887         SKIP_IF(!perf_breakpoint_supported());
888
889         return runtest();
890 }
891
892 int main(int argc, char *argv[], char **envp)
893 {
894         return test_harness(perf_hwbreak, "perf_hwbreak");
895 }