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
50int nprocs;
51
52static volatile int a = 10;
53static volatile int b = 10;
54static volatile char c[512 + 8] __attribute__((aligned(512)));
55
56static 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
73static int
74perf_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
82static 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
90static 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
98static 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
106static 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
121static 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
129static 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
137static 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
145static 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
197done:
198	CPU_FREE(mask);
199	return ret;
200}
201
202static 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
214static inline bool perf_breakpoint_supported(void)
215{
216	return breakpoint_test(4);
217}
218
219static inline bool dawr_supported(void)
220{
221	return breakpoint_test(DAWR_LENGTH_MAX);
222}
223
224static 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
292static 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
396static void multi_dawr_workload(void)
397{
398	a += 10;
399	b += 10;
400	c[512 + 1] += 'a';
401}
402
403static 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
448static 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
493static 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
538static 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
583static 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
627static 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
671static 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
715static 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
759static 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
775static 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. */
809static 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
837static 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
883static int perf_hwbreak(void)
884{
885	srand ( time(NULL) );
886
887	SKIP_IF_MSG(!perf_breakpoint_supported(), "Perf breakpoints not supported");
888
889	return runtest();
890}
891
892int main(int argc, char *argv[], char **envp)
893{
894	return test_harness(perf_hwbreak, "perf_hwbreak");
895}
896