xref: /openbmc/linux/arch/s390/lib/test_unwind.c (revision 22a41e9a5044bf3519f05b4a00e99af34bfeb40c)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Test module for unwind_for_each_frame
4  */
5 
6 #include <kunit/test.h>
7 #include <asm/unwind.h>
8 #include <linux/completion.h>
9 #include <linux/kallsyms.h>
10 #include <linux/kthread.h>
11 #include <linux/ftrace.h>
12 #include <linux/module.h>
13 #include <linux/timer.h>
14 #include <linux/slab.h>
15 #include <linux/string.h>
16 #include <linux/kprobes.h>
17 #include <linux/wait.h>
18 #include <asm/irq.h>
19 
20 static struct kunit *current_test;
21 
22 #define BT_BUF_SIZE (PAGE_SIZE * 4)
23 
24 static bool force_bt;
25 module_param_named(backtrace, force_bt, bool, 0444);
26 MODULE_PARM_DESC(backtrace, "print backtraces for all tests");
27 
28 /*
29  * To avoid printk line limit split backtrace by lines
30  */
31 static void print_backtrace(char *bt)
32 {
33 	char *p;
34 
35 	while (true) {
36 		p = strsep(&bt, "\n");
37 		if (!p)
38 			break;
39 		kunit_err(current_test, "%s\n", p);
40 	}
41 }
42 
43 /*
44  * Calls unwind_for_each_frame(task, regs, sp) and verifies that the result
45  * contains unwindme_func2 followed by unwindme_func1.
46  */
47 static noinline int test_unwind(struct task_struct *task, struct pt_regs *regs,
48 				unsigned long sp)
49 {
50 	int frame_count, prev_is_func2, seen_func2_func1;
51 	const int max_frames = 128;
52 	struct unwind_state state;
53 	size_t bt_pos = 0;
54 	int ret = 0;
55 	char *bt;
56 
57 	bt = kmalloc(BT_BUF_SIZE, GFP_ATOMIC);
58 	if (!bt) {
59 		kunit_err(current_test, "failed to allocate backtrace buffer\n");
60 		return -ENOMEM;
61 	}
62 	/* Unwind. */
63 	frame_count = 0;
64 	prev_is_func2 = 0;
65 	seen_func2_func1 = 0;
66 	unwind_for_each_frame(&state, task, regs, sp) {
67 		unsigned long addr = unwind_get_return_address(&state);
68 		char sym[KSYM_SYMBOL_LEN];
69 
70 		if (frame_count++ == max_frames)
71 			break;
72 		if (state.reliable && !addr) {
73 			kunit_err(current_test, "unwind state reliable but addr is 0\n");
74 			ret = -EINVAL;
75 			break;
76 		}
77 		sprint_symbol(sym, addr);
78 		if (bt_pos < BT_BUF_SIZE) {
79 			bt_pos += snprintf(bt + bt_pos, BT_BUF_SIZE - bt_pos,
80 					   state.reliable ? " [%-7s%px] %pSR\n" :
81 							    "([%-7s%px] %pSR)\n",
82 					   stack_type_name(state.stack_info.type),
83 					   (void *)state.sp, (void *)state.ip);
84 			if (bt_pos >= BT_BUF_SIZE)
85 				kunit_err(current_test, "backtrace buffer is too small\n");
86 		}
87 		frame_count += 1;
88 		if (prev_is_func2 && str_has_prefix(sym, "unwindme_func1"))
89 			seen_func2_func1 = 1;
90 		prev_is_func2 = str_has_prefix(sym, "unwindme_func2");
91 	}
92 
93 	/* Check the results. */
94 	if (unwind_error(&state)) {
95 		kunit_err(current_test, "unwind error\n");
96 		ret = -EINVAL;
97 	}
98 	if (!seen_func2_func1) {
99 		kunit_err(current_test, "unwindme_func2 and unwindme_func1 not found\n");
100 		ret = -EINVAL;
101 	}
102 	if (frame_count == max_frames) {
103 		kunit_err(current_test, "Maximum number of frames exceeded\n");
104 		ret = -EINVAL;
105 	}
106 	if (ret || force_bt)
107 		print_backtrace(bt);
108 	kfree(bt);
109 	return ret;
110 }
111 
112 /* State of the task being unwound. */
113 struct unwindme {
114 	int flags;
115 	int ret;
116 	struct task_struct *task;
117 	struct completion task_ready;
118 	wait_queue_head_t task_wq;
119 	unsigned long sp;
120 };
121 
122 static struct unwindme *unwindme;
123 
124 /* Values of unwindme.flags. */
125 #define UWM_DEFAULT		0x0
126 #define UWM_THREAD		0x1	/* Unwind a separate task. */
127 #define UWM_REGS		0x2	/* Pass regs to test_unwind(). */
128 #define UWM_SP			0x4	/* Pass sp to test_unwind(). */
129 #define UWM_CALLER		0x8	/* Unwind starting from caller. */
130 #define UWM_SWITCH_STACK	0x10	/* Use call_on_stack. */
131 #define UWM_IRQ			0x20	/* Unwind from irq context. */
132 #define UWM_PGM			0x40	/* Unwind from program check handler */
133 #define UWM_KPROBE_ON_FTRACE	0x80	/* Unwind from kprobe handler called via ftrace. */
134 #define UWM_FTRACE		0x100	/* Unwind from ftrace handler. */
135 #define UWM_KRETPROBE		0x200	/* Unwind kretprobe handlers. */
136 
137 static __always_inline unsigned long get_psw_addr(void)
138 {
139 	unsigned long psw_addr;
140 
141 	asm volatile(
142 		"basr	%[psw_addr],0\n"
143 		: [psw_addr] "=d" (psw_addr));
144 	return psw_addr;
145 }
146 
147 static int kretprobe_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
148 {
149 	struct unwindme *u = unwindme;
150 
151 	u->ret = test_unwind(NULL, (u->flags & UWM_REGS) ? regs : NULL,
152 			     (u->flags & UWM_SP) ? u->sp : 0);
153 
154 	return 0;
155 }
156 
157 static noinline notrace void test_unwind_kretprobed_func(void)
158 {
159 	asm volatile("	nop\n");
160 }
161 
162 static noinline void test_unwind_kretprobed_func_caller(void)
163 {
164 	test_unwind_kretprobed_func();
165 }
166 
167 static int test_unwind_kretprobe(struct unwindme *u)
168 {
169 	int ret;
170 	struct kretprobe my_kretprobe;
171 
172 	if (!IS_ENABLED(CONFIG_KPROBES))
173 		kunit_skip(current_test, "requires CONFIG_KPROBES");
174 
175 	u->ret = -1; /* make sure kprobe is called */
176 	unwindme = u;
177 
178 	memset(&my_kretprobe, 0, sizeof(my_kretprobe));
179 	my_kretprobe.handler = kretprobe_ret_handler;
180 	my_kretprobe.maxactive = 1;
181 	my_kretprobe.kp.addr = (kprobe_opcode_t *)test_unwind_kretprobed_func;
182 
183 	ret = register_kretprobe(&my_kretprobe);
184 
185 	if (ret < 0) {
186 		kunit_err(current_test, "register_kretprobe failed %d\n", ret);
187 		return -EINVAL;
188 	}
189 
190 	test_unwind_kretprobed_func_caller();
191 	unregister_kretprobe(&my_kretprobe);
192 	unwindme = NULL;
193 	return u->ret;
194 }
195 
196 static int kprobe_pre_handler(struct kprobe *p, struct pt_regs *regs)
197 {
198 	struct unwindme *u = unwindme;
199 
200 	u->ret = test_unwind(NULL, (u->flags & UWM_REGS) ? regs : NULL,
201 			     (u->flags & UWM_SP) ? u->sp : 0);
202 	return 0;
203 }
204 
205 extern const char test_unwind_kprobed_insn[];
206 
207 static noinline void test_unwind_kprobed_func(void)
208 {
209 	asm volatile(
210 		"	nopr	%%r7\n"
211 		"test_unwind_kprobed_insn:\n"
212 		"	nopr	%%r7\n"
213 		:);
214 }
215 
216 static int test_unwind_kprobe(struct unwindme *u)
217 {
218 	struct kprobe kp;
219 	int ret;
220 
221 	if (!IS_ENABLED(CONFIG_KPROBES))
222 		kunit_skip(current_test, "requires CONFIG_KPROBES");
223 	if (!IS_ENABLED(CONFIG_KPROBES_ON_FTRACE) && u->flags & UWM_KPROBE_ON_FTRACE)
224 		kunit_skip(current_test, "requires CONFIG_KPROBES_ON_FTRACE");
225 
226 	u->ret = -1; /* make sure kprobe is called */
227 	unwindme = u;
228 	memset(&kp, 0, sizeof(kp));
229 	kp.pre_handler = kprobe_pre_handler;
230 	kp.addr = u->flags & UWM_KPROBE_ON_FTRACE ?
231 				(kprobe_opcode_t *)test_unwind_kprobed_func :
232 				(kprobe_opcode_t *)test_unwind_kprobed_insn;
233 	ret = register_kprobe(&kp);
234 	if (ret < 0) {
235 		kunit_err(current_test, "register_kprobe failed %d\n", ret);
236 		return -EINVAL;
237 	}
238 
239 	test_unwind_kprobed_func();
240 	unregister_kprobe(&kp);
241 	unwindme = NULL;
242 	return u->ret;
243 }
244 
245 static void notrace __used test_unwind_ftrace_handler(unsigned long ip,
246 						      unsigned long parent_ip,
247 						      struct ftrace_ops *fops,
248 						      struct ftrace_regs *fregs)
249 {
250 	struct unwindme *u = (struct unwindme *)fregs->regs.gprs[2];
251 
252 	u->ret = test_unwind(NULL, (u->flags & UWM_REGS) ? &fregs->regs : NULL,
253 			     (u->flags & UWM_SP) ? u->sp : 0);
254 }
255 
256 static noinline int test_unwind_ftraced_func(struct unwindme *u)
257 {
258 	return READ_ONCE(u)->ret;
259 }
260 
261 static int test_unwind_ftrace(struct unwindme *u)
262 {
263 	int ret;
264 #ifdef CONFIG_DYNAMIC_FTRACE
265 	struct ftrace_ops *fops;
266 
267 	fops = kunit_kzalloc(current_test, sizeof(*fops), GFP_KERNEL);
268 	fops->func = test_unwind_ftrace_handler;
269 	fops->flags = FTRACE_OPS_FL_DYNAMIC |
270 		     FTRACE_OPS_FL_RECURSION |
271 		     FTRACE_OPS_FL_SAVE_REGS |
272 		     FTRACE_OPS_FL_PERMANENT;
273 #else
274 	kunit_skip(current_test, "requires CONFIG_DYNAMIC_FTRACE");
275 #endif
276 
277 	ret = ftrace_set_filter_ip(fops, (unsigned long)test_unwind_ftraced_func, 0, 0);
278 	if (ret) {
279 		kunit_err(current_test, "failed to set ftrace filter (%d)\n", ret);
280 		return -1;
281 	}
282 
283 	ret = register_ftrace_function(fops);
284 	if (!ret) {
285 		ret = test_unwind_ftraced_func(u);
286 		unregister_ftrace_function(fops);
287 	} else {
288 		kunit_err(current_test, "failed to register ftrace handler (%d)\n", ret);
289 	}
290 
291 	ftrace_set_filter_ip(fops, (unsigned long)test_unwind_ftraced_func, 1, 0);
292 	return ret;
293 }
294 
295 /* This function may or may not appear in the backtrace. */
296 static noinline int unwindme_func4(struct unwindme *u)
297 {
298 	if (!(u->flags & UWM_CALLER))
299 		u->sp = current_frame_address();
300 	if (u->flags & UWM_THREAD) {
301 		complete(&u->task_ready);
302 		wait_event(u->task_wq, kthread_should_park());
303 		kthread_parkme();
304 		return 0;
305 	} else if (u->flags & (UWM_PGM | UWM_KPROBE_ON_FTRACE)) {
306 		return test_unwind_kprobe(u);
307 	} else if (u->flags & (UWM_KRETPROBE)) {
308 		return test_unwind_kretprobe(u);
309 	} else if (u->flags & UWM_FTRACE) {
310 		return test_unwind_ftrace(u);
311 	} else {
312 		struct pt_regs regs;
313 
314 		memset(&regs, 0, sizeof(regs));
315 		regs.psw.addr = get_psw_addr();
316 		regs.gprs[15] = current_stack_pointer();
317 		return test_unwind(NULL,
318 				   (u->flags & UWM_REGS) ? &regs : NULL,
319 				   (u->flags & UWM_SP) ? u->sp : 0);
320 	}
321 }
322 
323 /* This function may or may not appear in the backtrace. */
324 static noinline int unwindme_func3(struct unwindme *u)
325 {
326 	u->sp = current_frame_address();
327 	return unwindme_func4(u);
328 }
329 
330 /* This function must appear in the backtrace. */
331 static noinline int unwindme_func2(struct unwindme *u)
332 {
333 	unsigned long flags;
334 	int rc;
335 
336 	if (u->flags & UWM_SWITCH_STACK) {
337 		local_irq_save(flags);
338 		local_mcck_disable();
339 		rc = call_on_stack(1, S390_lowcore.nodat_stack,
340 				   int, unwindme_func3, struct unwindme *, u);
341 		local_mcck_enable();
342 		local_irq_restore(flags);
343 		return rc;
344 	} else {
345 		return unwindme_func3(u);
346 	}
347 }
348 
349 /* This function must follow unwindme_func2 in the backtrace. */
350 static noinline int unwindme_func1(void *u)
351 {
352 	return unwindme_func2((struct unwindme *)u);
353 }
354 
355 static void unwindme_timer_fn(struct timer_list *unused)
356 {
357 	struct unwindme *u = READ_ONCE(unwindme);
358 
359 	if (u) {
360 		unwindme = NULL;
361 		u->task = NULL;
362 		u->ret = unwindme_func1(u);
363 		complete(&u->task_ready);
364 	}
365 }
366 
367 static struct timer_list unwind_timer;
368 
369 static int test_unwind_irq(struct unwindme *u)
370 {
371 	unwindme = u;
372 	init_completion(&u->task_ready);
373 	timer_setup(&unwind_timer, unwindme_timer_fn, 0);
374 	mod_timer(&unwind_timer, jiffies + 1);
375 	wait_for_completion(&u->task_ready);
376 	return u->ret;
377 }
378 
379 /* Spawns a task and passes it to test_unwind(). */
380 static int test_unwind_task(struct unwindme *u)
381 {
382 	struct task_struct *task;
383 	int ret;
384 
385 	/* Initialize thread-related fields. */
386 	init_completion(&u->task_ready);
387 	init_waitqueue_head(&u->task_wq);
388 
389 	/*
390 	 * Start the task and wait until it reaches unwindme_func4() and sleeps
391 	 * in (task_ready, unwind_done] range.
392 	 */
393 	task = kthread_run(unwindme_func1, u, "%s", __func__);
394 	if (IS_ERR(task)) {
395 		kunit_err(current_test, "kthread_run() failed\n");
396 		return PTR_ERR(task);
397 	}
398 	/*
399 	 * Make sure task reaches unwindme_func4 before parking it,
400 	 * we might park it before kthread function has been executed otherwise
401 	 */
402 	wait_for_completion(&u->task_ready);
403 	kthread_park(task);
404 	/* Unwind. */
405 	ret = test_unwind(task, NULL, (u->flags & UWM_SP) ? u->sp : 0);
406 	kthread_stop(task);
407 	return ret;
408 }
409 
410 struct test_params {
411 	int flags;
412 	char *name;
413 };
414 
415 /*
416  * Create required parameter list for tests
417  */
418 #define TEST_WITH_FLAGS(f) { .flags = f, .name = #f }
419 static const struct test_params param_list[] = {
420 	TEST_WITH_FLAGS(UWM_DEFAULT),
421 	TEST_WITH_FLAGS(UWM_SP),
422 	TEST_WITH_FLAGS(UWM_REGS),
423 	TEST_WITH_FLAGS(UWM_SWITCH_STACK),
424 	TEST_WITH_FLAGS(UWM_SP | UWM_REGS),
425 	TEST_WITH_FLAGS(UWM_CALLER | UWM_SP),
426 	TEST_WITH_FLAGS(UWM_CALLER | UWM_SP | UWM_REGS),
427 	TEST_WITH_FLAGS(UWM_CALLER | UWM_SP | UWM_REGS | UWM_SWITCH_STACK),
428 	TEST_WITH_FLAGS(UWM_THREAD),
429 	TEST_WITH_FLAGS(UWM_THREAD | UWM_SP),
430 	TEST_WITH_FLAGS(UWM_THREAD | UWM_CALLER | UWM_SP),
431 	TEST_WITH_FLAGS(UWM_IRQ),
432 	TEST_WITH_FLAGS(UWM_IRQ | UWM_SWITCH_STACK),
433 	TEST_WITH_FLAGS(UWM_IRQ | UWM_SP),
434 	TEST_WITH_FLAGS(UWM_IRQ | UWM_REGS),
435 	TEST_WITH_FLAGS(UWM_IRQ | UWM_SP | UWM_REGS),
436 	TEST_WITH_FLAGS(UWM_IRQ | UWM_CALLER | UWM_SP),
437 	TEST_WITH_FLAGS(UWM_IRQ | UWM_CALLER | UWM_SP | UWM_REGS),
438 	TEST_WITH_FLAGS(UWM_IRQ | UWM_CALLER | UWM_SP | UWM_REGS | UWM_SWITCH_STACK),
439 	TEST_WITH_FLAGS(UWM_PGM),
440 	TEST_WITH_FLAGS(UWM_PGM | UWM_SP),
441 	TEST_WITH_FLAGS(UWM_PGM | UWM_REGS),
442 	TEST_WITH_FLAGS(UWM_PGM | UWM_SP | UWM_REGS),
443 	TEST_WITH_FLAGS(UWM_KPROBE_ON_FTRACE),
444 	TEST_WITH_FLAGS(UWM_KPROBE_ON_FTRACE | UWM_SP),
445 	TEST_WITH_FLAGS(UWM_KPROBE_ON_FTRACE | UWM_REGS),
446 	TEST_WITH_FLAGS(UWM_KPROBE_ON_FTRACE | UWM_SP | UWM_REGS),
447 	TEST_WITH_FLAGS(UWM_FTRACE),
448 	TEST_WITH_FLAGS(UWM_FTRACE | UWM_SP),
449 	TEST_WITH_FLAGS(UWM_FTRACE | UWM_REGS),
450 	TEST_WITH_FLAGS(UWM_FTRACE | UWM_SP | UWM_REGS),
451 	TEST_WITH_FLAGS(UWM_KRETPROBE),
452 	TEST_WITH_FLAGS(UWM_KRETPROBE | UWM_SP),
453 	TEST_WITH_FLAGS(UWM_KRETPROBE | UWM_REGS),
454 	TEST_WITH_FLAGS(UWM_KRETPROBE | UWM_SP | UWM_REGS),
455 };
456 
457 /*
458  * Parameter description generator: required for KUNIT_ARRAY_PARAM()
459  */
460 static void get_desc(const struct test_params *params, char *desc)
461 {
462 	strscpy(desc, params->name, KUNIT_PARAM_DESC_SIZE);
463 }
464 
465 /*
466  * Create test_unwind_gen_params
467  */
468 KUNIT_ARRAY_PARAM(test_unwind, param_list, get_desc);
469 
470 static void test_unwind_flags(struct kunit *test)
471 {
472 	struct unwindme u;
473 	const struct test_params *params;
474 
475 	current_test = test;
476 	params = (const struct test_params *)test->param_value;
477 	u.flags = params->flags;
478 	if (u.flags & UWM_THREAD)
479 		KUNIT_EXPECT_EQ(test, 0, test_unwind_task(&u));
480 	else if (u.flags & UWM_IRQ)
481 		KUNIT_EXPECT_EQ(test, 0, test_unwind_irq(&u));
482 	else
483 		KUNIT_EXPECT_EQ(test, 0, unwindme_func1(&u));
484 }
485 
486 static struct kunit_case unwind_test_cases[] = {
487 	KUNIT_CASE_PARAM(test_unwind_flags, test_unwind_gen_params),
488 	{}
489 };
490 
491 static struct kunit_suite test_unwind_suite = {
492 	.name = "test_unwind",
493 	.test_cases = unwind_test_cases,
494 };
495 
496 kunit_test_suites(&test_unwind_suite);
497 
498 MODULE_LICENSE("GPL");
499