2929
3030static int fd1 ;
3131static int fd2 ;
32+ static int fd3 ;
3233static int overflows ;
34+ static int overflows_2 ;
35+
36+ volatile long the_var ;
37+
38+
39+ /*
40+ * Use ASM to ensure watchpoint and breakpoint can be triggered
41+ * at one instruction.
42+ */
43+ #if defined (__x86_64__ )
44+ extern void __test_function (volatile long * ptr );
45+ asm (
46+ ".globl __test_function\n"
47+ "__test_function:\n"
48+ "incq (%rdi)\n"
49+ "ret\n" );
50+ #elif defined (__aarch64__ )
51+ extern void __test_function (volatile long * ptr );
52+ asm (
53+ ".globl __test_function\n"
54+ "__test_function:\n"
55+ "str x30, [x0]\n"
56+ "ret\n" );
57+
58+ #else
59+ static void __test_function (volatile long * ptr )
60+ {
61+ * ptr = 0x1234 ;
62+ }
63+ #endif
3364
3465__attribute__ ((noinline ))
3566static int test_function (void )
3667{
68+ __test_function (& the_var );
69+ the_var ++ ;
3770 return time (NULL );
3871}
3972
73+ static void sig_handler_2 (int signum __maybe_unused ,
74+ siginfo_t * oh __maybe_unused ,
75+ void * uc __maybe_unused )
76+ {
77+ overflows_2 ++ ;
78+ if (overflows_2 > 10 ) {
79+ ioctl (fd1 , PERF_EVENT_IOC_DISABLE , 0 );
80+ ioctl (fd2 , PERF_EVENT_IOC_DISABLE , 0 );
81+ ioctl (fd3 , PERF_EVENT_IOC_DISABLE , 0 );
82+ }
83+ }
84+
4085static void sig_handler (int signum __maybe_unused ,
4186 siginfo_t * oh __maybe_unused ,
4287 void * uc __maybe_unused )
@@ -54,10 +99,11 @@ static void sig_handler(int signum __maybe_unused,
5499 */
55100 ioctl (fd1 , PERF_EVENT_IOC_DISABLE , 0 );
56101 ioctl (fd2 , PERF_EVENT_IOC_DISABLE , 0 );
102+ ioctl (fd3 , PERF_EVENT_IOC_DISABLE , 0 );
57103 }
58104}
59105
60- static int bp_event ( void * fn , int setup_signal )
106+ static int __event ( bool is_x , void * addr , int signal )
61107{
62108 struct perf_event_attr pe ;
63109 int fd ;
@@ -67,8 +113,8 @@ static int bp_event(void *fn, int setup_signal)
67113 pe .size = sizeof (struct perf_event_attr );
68114
69115 pe .config = 0 ;
70- pe .bp_type = HW_BREAKPOINT_X ;
71- pe .bp_addr = (unsigned long ) fn ;
116+ pe .bp_type = is_x ? HW_BREAKPOINT_X : HW_BREAKPOINT_W ;
117+ pe .bp_addr = (unsigned long ) addr ;
72118 pe .bp_len = sizeof (long );
73119
74120 pe .sample_period = 1 ;
@@ -86,17 +132,25 @@ static int bp_event(void *fn, int setup_signal)
86132 return TEST_FAIL ;
87133 }
88134
89- if (setup_signal ) {
90- fcntl (fd , F_SETFL , O_RDWR |O_NONBLOCK |O_ASYNC );
91- fcntl (fd , F_SETSIG , SIGIO );
92- fcntl (fd , F_SETOWN , getpid ());
93- }
135+ fcntl (fd , F_SETFL , O_RDWR |O_NONBLOCK |O_ASYNC );
136+ fcntl (fd , F_SETSIG , signal );
137+ fcntl (fd , F_SETOWN , getpid ());
94138
95139 ioctl (fd , PERF_EVENT_IOC_RESET , 0 );
96140
97141 return fd ;
98142}
99143
144+ static int bp_event (void * addr , int signal )
145+ {
146+ return __event (true, addr , signal );
147+ }
148+
149+ static int wp_event (void * addr , int signal )
150+ {
151+ return __event (false, addr , signal );
152+ }
153+
100154static long long bp_count (int fd )
101155{
102156 long long count ;
@@ -114,7 +168,7 @@ static long long bp_count(int fd)
114168int test__bp_signal (int subtest __maybe_unused )
115169{
116170 struct sigaction sa ;
117- long long count1 , count2 ;
171+ long long count1 , count2 , count3 ;
118172
119173 /* setup SIGIO signal handler */
120174 memset (& sa , 0 , sizeof (struct sigaction ));
@@ -126,21 +180,52 @@ int test__bp_signal(int subtest __maybe_unused)
126180 return TEST_FAIL ;
127181 }
128182
183+ sa .sa_sigaction = (void * ) sig_handler_2 ;
184+ if (sigaction (SIGUSR1 , & sa , NULL ) < 0 ) {
185+ pr_debug ("failed setting up signal handler 2\n" );
186+ return TEST_FAIL ;
187+ }
188+
129189 /*
130190 * We create following events:
131191 *
132- * fd1 - breakpoint event on test_function with SIGIO
192+ * fd1 - breakpoint event on __test_function with SIGIO
133193 * signal configured. We should get signal
134194 * notification each time the breakpoint is hit
135195 *
136- * fd2 - breakpoint event on sig_handler without SIGIO
196+ * fd2 - breakpoint event on sig_handler with SIGUSR1
197+ * configured. We should get SIGUSR1 each time when
198+ * breakpoint is hit
199+ *
200+ * fd3 - watchpoint event on __test_function with SIGIO
137201 * configured.
138202 *
139203 * Following processing should happen:
140- * - execute test_function
141- * - fd1 event breakpoint hit -> count1 == 1
142- * - SIGIO is delivered -> overflows == 1
143- * - fd2 event breakpoint hit -> count2 == 1
204+ * Exec: Action: Result:
205+ * incq (%rdi) - fd1 event breakpoint hit -> count1 == 1
206+ * - SIGIO is delivered
207+ * sig_handler - fd2 event breakpoint hit -> count2 == 1
208+ * - SIGUSR1 is delivered
209+ * sig_handler_2 -> overflows_2 == 1 (nested signal)
210+ * sys_rt_sigreturn - return from sig_handler_2
211+ * overflows++ -> overflows = 1
212+ * sys_rt_sigreturn - return from sig_handler
213+ * incq (%rdi) - fd3 event watchpoint hit -> count3 == 1 (wp and bp in one insn)
214+ * - SIGIO is delivered
215+ * sig_handler - fd2 event breakpoint hit -> count2 == 2
216+ * - SIGUSR1 is delivered
217+ * sig_handler_2 -> overflows_2 == 2 (nested signal)
218+ * sys_rt_sigreturn - return from sig_handler_2
219+ * overflows++ -> overflows = 2
220+ * sys_rt_sigreturn - return from sig_handler
221+ * the_var++ - fd3 event watchpoint hit -> count3 == 2 (standalone watchpoint)
222+ * - SIGIO is delivered
223+ * sig_handler - fd2 event breakpoint hit -> count2 == 3
224+ * - SIGUSR1 is delivered
225+ * sig_handler_2 -> overflows_2 == 3 (nested signal)
226+ * sys_rt_sigreturn - return from sig_handler_2
227+ * overflows++ -> overflows == 3
228+ * sys_rt_sigreturn - return from sig_handler
144229 *
145230 * The test case check following error conditions:
146231 * - we get stuck in signal handler because of debug
@@ -152,11 +237,13 @@ int test__bp_signal(int subtest __maybe_unused)
152237 *
153238 */
154239
155- fd1 = bp_event (test_function , 1 );
156- fd2 = bp_event (sig_handler , 0 );
240+ fd1 = bp_event (__test_function , SIGIO );
241+ fd2 = bp_event (sig_handler , SIGUSR1 );
242+ fd3 = wp_event ((void * )& the_var , SIGIO );
157243
158244 ioctl (fd1 , PERF_EVENT_IOC_ENABLE , 0 );
159245 ioctl (fd2 , PERF_EVENT_IOC_ENABLE , 0 );
246+ ioctl (fd3 , PERF_EVENT_IOC_ENABLE , 0 );
160247
161248 /*
162249 * Kick off the test by trigering 'fd1'
@@ -166,15 +253,18 @@ int test__bp_signal(int subtest __maybe_unused)
166253
167254 ioctl (fd1 , PERF_EVENT_IOC_DISABLE , 0 );
168255 ioctl (fd2 , PERF_EVENT_IOC_DISABLE , 0 );
256+ ioctl (fd3 , PERF_EVENT_IOC_DISABLE , 0 );
169257
170258 count1 = bp_count (fd1 );
171259 count2 = bp_count (fd2 );
260+ count3 = bp_count (fd3 );
172261
173262 close (fd1 );
174263 close (fd2 );
264+ close (fd3 );
175265
176- pr_debug ("count1 %lld, count2 %lld, overflow %d\n" ,
177- count1 , count2 , overflows );
266+ pr_debug ("count1 %lld, count2 %lld, count3 %lld, overflow %d, overflows_2 %d\n" ,
267+ count1 , count2 , count3 , overflows , overflows_2 );
178268
179269 if (count1 != 1 ) {
180270 if (count1 == 11 )
@@ -183,12 +273,18 @@ int test__bp_signal(int subtest __maybe_unused)
183273 pr_debug ("failed: wrong count for bp1%lld\n" , count1 );
184274 }
185275
186- if (overflows != 1 )
276+ if (overflows != 3 )
187277 pr_debug ("failed: wrong overflow hit\n" );
188278
189- if (count2 != 1 )
279+ if (overflows_2 != 3 )
280+ pr_debug ("failed: wrong overflow_2 hit\n" );
281+
282+ if (count2 != 3 )
190283 pr_debug ("failed: wrong count for bp2\n" );
191284
192- return count1 == 1 && overflows == 1 && count2 == 1 ?
285+ if (count3 != 2 )
286+ pr_debug ("failed: wrong count for bp3\n" );
287+
288+ return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ?
193289 TEST_OK : TEST_FAIL ;
194290}
0 commit comments