Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Test module for unwind_for_each_frame
0004  */
0005 
0006 #include <kunit/test.h>
0007 #include <asm/unwind.h>
0008 #include <linux/completion.h>
0009 #include <linux/kallsyms.h>
0010 #include <linux/kthread.h>
0011 #include <linux/ftrace.h>
0012 #include <linux/module.h>
0013 #include <linux/timer.h>
0014 #include <linux/slab.h>
0015 #include <linux/string.h>
0016 #include <linux/kprobes.h>
0017 #include <linux/wait.h>
0018 #include <asm/irq.h>
0019 
0020 static struct kunit *current_test;
0021 
0022 #define BT_BUF_SIZE (PAGE_SIZE * 4)
0023 
0024 static bool force_bt;
0025 module_param_named(backtrace, force_bt, bool, 0444);
0026 MODULE_PARM_DESC(backtrace, "print backtraces for all tests");
0027 
0028 /*
0029  * To avoid printk line limit split backtrace by lines
0030  */
0031 static void print_backtrace(char *bt)
0032 {
0033     char *p;
0034 
0035     while (true) {
0036         p = strsep(&bt, "\n");
0037         if (!p)
0038             break;
0039         kunit_err(current_test, "%s\n", p);
0040     }
0041 }
0042 
0043 /*
0044  * Calls unwind_for_each_frame(task, regs, sp) and verifies that the result
0045  * contains unwindme_func2 followed by unwindme_func1.
0046  */
0047 static noinline int test_unwind(struct task_struct *task, struct pt_regs *regs,
0048                 unsigned long sp)
0049 {
0050     int frame_count, prev_is_func2, seen_func2_func1, seen_kretprobe_trampoline;
0051     const int max_frames = 128;
0052     struct unwind_state state;
0053     size_t bt_pos = 0;
0054     int ret = 0;
0055     char *bt;
0056 
0057     bt = kmalloc(BT_BUF_SIZE, GFP_ATOMIC);
0058     if (!bt) {
0059         kunit_err(current_test, "failed to allocate backtrace buffer\n");
0060         return -ENOMEM;
0061     }
0062     /* Unwind. */
0063     frame_count = 0;
0064     prev_is_func2 = 0;
0065     seen_func2_func1 = 0;
0066     seen_kretprobe_trampoline = 0;
0067     unwind_for_each_frame(&state, task, regs, sp) {
0068         unsigned long addr = unwind_get_return_address(&state);
0069         char sym[KSYM_SYMBOL_LEN];
0070 
0071         if (frame_count++ == max_frames)
0072             break;
0073         if (state.reliable && !addr) {
0074             kunit_err(current_test, "unwind state reliable but addr is 0\n");
0075             ret = -EINVAL;
0076             break;
0077         }
0078         sprint_symbol(sym, addr);
0079         if (bt_pos < BT_BUF_SIZE) {
0080             bt_pos += snprintf(bt + bt_pos, BT_BUF_SIZE - bt_pos,
0081                        state.reliable ? " [%-7s%px] %pSR\n" :
0082                                 "([%-7s%px] %pSR)\n",
0083                        stack_type_name(state.stack_info.type),
0084                        (void *)state.sp, (void *)state.ip);
0085             if (bt_pos >= BT_BUF_SIZE)
0086                 kunit_err(current_test, "backtrace buffer is too small\n");
0087         }
0088         frame_count += 1;
0089         if (prev_is_func2 && str_has_prefix(sym, "unwindme_func1"))
0090             seen_func2_func1 = 1;
0091         prev_is_func2 = str_has_prefix(sym, "unwindme_func2");
0092         if (str_has_prefix(sym, "__kretprobe_trampoline+0x0/"))
0093             seen_kretprobe_trampoline = 1;
0094     }
0095 
0096     /* Check the results. */
0097     if (unwind_error(&state)) {
0098         kunit_err(current_test, "unwind error\n");
0099         ret = -EINVAL;
0100     }
0101     if (!seen_func2_func1) {
0102         kunit_err(current_test, "unwindme_func2 and unwindme_func1 not found\n");
0103         ret = -EINVAL;
0104     }
0105     if (frame_count == max_frames) {
0106         kunit_err(current_test, "Maximum number of frames exceeded\n");
0107         ret = -EINVAL;
0108     }
0109     if (seen_kretprobe_trampoline) {
0110         kunit_err(current_test, "__kretprobe_trampoline+0x0 in unwinding results\n");
0111         ret = -EINVAL;
0112     }
0113     if (ret || force_bt)
0114         print_backtrace(bt);
0115     kfree(bt);
0116     return ret;
0117 }
0118 
0119 /* State of the task being unwound. */
0120 struct unwindme {
0121     int flags;
0122     int ret;
0123     struct task_struct *task;
0124     struct completion task_ready;
0125     wait_queue_head_t task_wq;
0126     unsigned long sp;
0127 };
0128 
0129 static struct unwindme *unwindme;
0130 
0131 /* Values of unwindme.flags. */
0132 #define UWM_DEFAULT     0x0
0133 #define UWM_THREAD      0x1 /* Unwind a separate task. */
0134 #define UWM_REGS        0x2 /* Pass regs to test_unwind(). */
0135 #define UWM_SP          0x4 /* Pass sp to test_unwind(). */
0136 #define UWM_CALLER      0x8 /* Unwind starting from caller. */
0137 #define UWM_SWITCH_STACK    0x10    /* Use call_on_stack. */
0138 #define UWM_IRQ         0x20    /* Unwind from irq context. */
0139 #define UWM_PGM         0x40    /* Unwind from program check handler */
0140 #define UWM_KPROBE_ON_FTRACE    0x80    /* Unwind from kprobe handler called via ftrace. */
0141 #define UWM_FTRACE      0x100   /* Unwind from ftrace handler. */
0142 #define UWM_KRETPROBE       0x200   /* Unwind through kretprobed function. */
0143 #define UWM_KRETPROBE_HANDLER   0x400   /* Unwind from kretprobe handler. */
0144 
0145 static __always_inline struct pt_regs fake_pt_regs(void)
0146 {
0147     struct pt_regs regs;
0148 
0149     memset(&regs, 0, sizeof(regs));
0150     regs.gprs[15] = current_stack_pointer;
0151 
0152     asm volatile(
0153         "basr   %[psw_addr],0\n"
0154         : [psw_addr] "=d" (regs.psw.addr));
0155     return regs;
0156 }
0157 
0158 static int kretprobe_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
0159 {
0160     struct unwindme *u = unwindme;
0161 
0162     if (!(u->flags & UWM_KRETPROBE_HANDLER))
0163         return 0;
0164 
0165     u->ret = test_unwind(NULL, (u->flags & UWM_REGS) ? regs : NULL,
0166                  (u->flags & UWM_SP) ? u->sp : 0);
0167 
0168     return 0;
0169 }
0170 
0171 static noinline notrace int test_unwind_kretprobed_func(struct unwindme *u)
0172 {
0173     struct pt_regs regs;
0174 
0175     if (!(u->flags & UWM_KRETPROBE))
0176         return 0;
0177 
0178     regs = fake_pt_regs();
0179     return test_unwind(NULL, (u->flags & UWM_REGS) ? &regs : NULL,
0180                (u->flags & UWM_SP) ? u->sp : 0);
0181 }
0182 
0183 static noinline int test_unwind_kretprobed_func_caller(struct unwindme *u)
0184 {
0185     return test_unwind_kretprobed_func(u);
0186 }
0187 
0188 static int test_unwind_kretprobe(struct unwindme *u)
0189 {
0190     int ret;
0191     struct kretprobe my_kretprobe;
0192 
0193     if (!IS_ENABLED(CONFIG_KPROBES))
0194         kunit_skip(current_test, "requires CONFIG_KPROBES");
0195 
0196     u->ret = -1; /* make sure kprobe is called */
0197     unwindme = u;
0198 
0199     memset(&my_kretprobe, 0, sizeof(my_kretprobe));
0200     my_kretprobe.handler = kretprobe_ret_handler;
0201     my_kretprobe.maxactive = 1;
0202     my_kretprobe.kp.addr = (kprobe_opcode_t *)test_unwind_kretprobed_func;
0203 
0204     ret = register_kretprobe(&my_kretprobe);
0205 
0206     if (ret < 0) {
0207         kunit_err(current_test, "register_kretprobe failed %d\n", ret);
0208         return -EINVAL;
0209     }
0210 
0211     ret = test_unwind_kretprobed_func_caller(u);
0212     unregister_kretprobe(&my_kretprobe);
0213     unwindme = NULL;
0214     if (u->flags & UWM_KRETPROBE_HANDLER)
0215         ret = u->ret;
0216     return ret;
0217 }
0218 
0219 static int kprobe_pre_handler(struct kprobe *p, struct pt_regs *regs)
0220 {
0221     struct unwindme *u = unwindme;
0222 
0223     u->ret = test_unwind(NULL, (u->flags & UWM_REGS) ? regs : NULL,
0224                  (u->flags & UWM_SP) ? u->sp : 0);
0225     return 0;
0226 }
0227 
0228 extern const char test_unwind_kprobed_insn[];
0229 
0230 static noinline void test_unwind_kprobed_func(void)
0231 {
0232     asm volatile(
0233         "   nopr    %%r7\n"
0234         "test_unwind_kprobed_insn:\n"
0235         "   nopr    %%r7\n"
0236         :);
0237 }
0238 
0239 static int test_unwind_kprobe(struct unwindme *u)
0240 {
0241     struct kprobe kp;
0242     int ret;
0243 
0244     if (!IS_ENABLED(CONFIG_KPROBES))
0245         kunit_skip(current_test, "requires CONFIG_KPROBES");
0246     if (!IS_ENABLED(CONFIG_KPROBES_ON_FTRACE) && u->flags & UWM_KPROBE_ON_FTRACE)
0247         kunit_skip(current_test, "requires CONFIG_KPROBES_ON_FTRACE");
0248 
0249     u->ret = -1; /* make sure kprobe is called */
0250     unwindme = u;
0251     memset(&kp, 0, sizeof(kp));
0252     kp.pre_handler = kprobe_pre_handler;
0253     kp.addr = u->flags & UWM_KPROBE_ON_FTRACE ?
0254                 (kprobe_opcode_t *)test_unwind_kprobed_func :
0255                 (kprobe_opcode_t *)test_unwind_kprobed_insn;
0256     ret = register_kprobe(&kp);
0257     if (ret < 0) {
0258         kunit_err(current_test, "register_kprobe failed %d\n", ret);
0259         return -EINVAL;
0260     }
0261 
0262     test_unwind_kprobed_func();
0263     unregister_kprobe(&kp);
0264     unwindme = NULL;
0265     return u->ret;
0266 }
0267 
0268 static void notrace __used test_unwind_ftrace_handler(unsigned long ip,
0269                               unsigned long parent_ip,
0270                               struct ftrace_ops *fops,
0271                               struct ftrace_regs *fregs)
0272 {
0273     struct unwindme *u = (struct unwindme *)fregs->regs.gprs[2];
0274 
0275     u->ret = test_unwind(NULL, (u->flags & UWM_REGS) ? &fregs->regs : NULL,
0276                  (u->flags & UWM_SP) ? u->sp : 0);
0277 }
0278 
0279 static noinline int test_unwind_ftraced_func(struct unwindme *u)
0280 {
0281     return READ_ONCE(u)->ret;
0282 }
0283 
0284 static int test_unwind_ftrace(struct unwindme *u)
0285 {
0286     int ret;
0287 #ifdef CONFIG_DYNAMIC_FTRACE
0288     struct ftrace_ops *fops;
0289 
0290     fops = kunit_kzalloc(current_test, sizeof(*fops), GFP_KERNEL);
0291     fops->func = test_unwind_ftrace_handler;
0292     fops->flags = FTRACE_OPS_FL_DYNAMIC |
0293              FTRACE_OPS_FL_RECURSION |
0294              FTRACE_OPS_FL_SAVE_REGS |
0295              FTRACE_OPS_FL_PERMANENT;
0296 #else
0297     kunit_skip(current_test, "requires CONFIG_DYNAMIC_FTRACE");
0298 #endif
0299 
0300     ret = ftrace_set_filter_ip(fops, (unsigned long)test_unwind_ftraced_func, 0, 0);
0301     if (ret) {
0302         kunit_err(current_test, "failed to set ftrace filter (%d)\n", ret);
0303         return -1;
0304     }
0305 
0306     ret = register_ftrace_function(fops);
0307     if (!ret) {
0308         ret = test_unwind_ftraced_func(u);
0309         unregister_ftrace_function(fops);
0310     } else {
0311         kunit_err(current_test, "failed to register ftrace handler (%d)\n", ret);
0312     }
0313 
0314     ftrace_set_filter_ip(fops, (unsigned long)test_unwind_ftraced_func, 1, 0);
0315     return ret;
0316 }
0317 
0318 /* This function may or may not appear in the backtrace. */
0319 static noinline int unwindme_func4(struct unwindme *u)
0320 {
0321     if (!(u->flags & UWM_CALLER))
0322         u->sp = current_frame_address();
0323     if (u->flags & UWM_THREAD) {
0324         complete(&u->task_ready);
0325         wait_event(u->task_wq, kthread_should_park());
0326         kthread_parkme();
0327         return 0;
0328     } else if (u->flags & (UWM_PGM | UWM_KPROBE_ON_FTRACE)) {
0329         return test_unwind_kprobe(u);
0330     } else if (u->flags & (UWM_KRETPROBE | UWM_KRETPROBE_HANDLER)) {
0331         return test_unwind_kretprobe(u);
0332     } else if (u->flags & UWM_FTRACE) {
0333         return test_unwind_ftrace(u);
0334     } else {
0335         struct pt_regs regs = fake_pt_regs();
0336 
0337         return test_unwind(NULL,
0338                    (u->flags & UWM_REGS) ? &regs : NULL,
0339                    (u->flags & UWM_SP) ? u->sp : 0);
0340     }
0341 }
0342 
0343 /* This function may or may not appear in the backtrace. */
0344 static noinline int unwindme_func3(struct unwindme *u)
0345 {
0346     u->sp = current_frame_address();
0347     return unwindme_func4(u);
0348 }
0349 
0350 /* This function must appear in the backtrace. */
0351 static noinline int unwindme_func2(struct unwindme *u)
0352 {
0353     unsigned long flags;
0354     int rc;
0355 
0356     if (u->flags & UWM_SWITCH_STACK) {
0357         local_irq_save(flags);
0358         local_mcck_disable();
0359         rc = call_on_stack(1, S390_lowcore.nodat_stack,
0360                    int, unwindme_func3, struct unwindme *, u);
0361         local_mcck_enable();
0362         local_irq_restore(flags);
0363         return rc;
0364     } else {
0365         return unwindme_func3(u);
0366     }
0367 }
0368 
0369 /* This function must follow unwindme_func2 in the backtrace. */
0370 static noinline int unwindme_func1(void *u)
0371 {
0372     return unwindme_func2((struct unwindme *)u);
0373 }
0374 
0375 static void unwindme_timer_fn(struct timer_list *unused)
0376 {
0377     struct unwindme *u = READ_ONCE(unwindme);
0378 
0379     if (u) {
0380         unwindme = NULL;
0381         u->task = NULL;
0382         u->ret = unwindme_func1(u);
0383         complete(&u->task_ready);
0384     }
0385 }
0386 
0387 static struct timer_list unwind_timer;
0388 
0389 static int test_unwind_irq(struct unwindme *u)
0390 {
0391     unwindme = u;
0392     init_completion(&u->task_ready);
0393     timer_setup(&unwind_timer, unwindme_timer_fn, 0);
0394     mod_timer(&unwind_timer, jiffies + 1);
0395     wait_for_completion(&u->task_ready);
0396     return u->ret;
0397 }
0398 
0399 /* Spawns a task and passes it to test_unwind(). */
0400 static int test_unwind_task(struct unwindme *u)
0401 {
0402     struct task_struct *task;
0403     int ret;
0404 
0405     /* Initialize thread-related fields. */
0406     init_completion(&u->task_ready);
0407     init_waitqueue_head(&u->task_wq);
0408 
0409     /*
0410      * Start the task and wait until it reaches unwindme_func4() and sleeps
0411      * in (task_ready, unwind_done] range.
0412      */
0413     task = kthread_run(unwindme_func1, u, "%s", __func__);
0414     if (IS_ERR(task)) {
0415         kunit_err(current_test, "kthread_run() failed\n");
0416         return PTR_ERR(task);
0417     }
0418     /*
0419      * Make sure task reaches unwindme_func4 before parking it,
0420      * we might park it before kthread function has been executed otherwise
0421      */
0422     wait_for_completion(&u->task_ready);
0423     kthread_park(task);
0424     /* Unwind. */
0425     ret = test_unwind(task, NULL, (u->flags & UWM_SP) ? u->sp : 0);
0426     kthread_stop(task);
0427     return ret;
0428 }
0429 
0430 struct test_params {
0431     int flags;
0432     char *name;
0433 };
0434 
0435 /*
0436  * Create required parameter list for tests
0437  */
0438 #define TEST_WITH_FLAGS(f) { .flags = f, .name = #f }
0439 static const struct test_params param_list[] = {
0440     TEST_WITH_FLAGS(UWM_DEFAULT),
0441     TEST_WITH_FLAGS(UWM_SP),
0442     TEST_WITH_FLAGS(UWM_REGS),
0443     TEST_WITH_FLAGS(UWM_SWITCH_STACK),
0444     TEST_WITH_FLAGS(UWM_SP | UWM_REGS),
0445     TEST_WITH_FLAGS(UWM_CALLER | UWM_SP),
0446     TEST_WITH_FLAGS(UWM_CALLER | UWM_SP | UWM_REGS),
0447     TEST_WITH_FLAGS(UWM_CALLER | UWM_SP | UWM_REGS | UWM_SWITCH_STACK),
0448     TEST_WITH_FLAGS(UWM_THREAD),
0449     TEST_WITH_FLAGS(UWM_THREAD | UWM_SP),
0450     TEST_WITH_FLAGS(UWM_THREAD | UWM_CALLER | UWM_SP),
0451     TEST_WITH_FLAGS(UWM_IRQ),
0452     TEST_WITH_FLAGS(UWM_IRQ | UWM_SWITCH_STACK),
0453     TEST_WITH_FLAGS(UWM_IRQ | UWM_SP),
0454     TEST_WITH_FLAGS(UWM_IRQ | UWM_REGS),
0455     TEST_WITH_FLAGS(UWM_IRQ | UWM_SP | UWM_REGS),
0456     TEST_WITH_FLAGS(UWM_IRQ | UWM_CALLER | UWM_SP),
0457     TEST_WITH_FLAGS(UWM_IRQ | UWM_CALLER | UWM_SP | UWM_REGS),
0458     TEST_WITH_FLAGS(UWM_IRQ | UWM_CALLER | UWM_SP | UWM_REGS | UWM_SWITCH_STACK),
0459     TEST_WITH_FLAGS(UWM_PGM),
0460     TEST_WITH_FLAGS(UWM_PGM | UWM_SP),
0461     TEST_WITH_FLAGS(UWM_PGM | UWM_REGS),
0462     TEST_WITH_FLAGS(UWM_PGM | UWM_SP | UWM_REGS),
0463     TEST_WITH_FLAGS(UWM_KPROBE_ON_FTRACE),
0464     TEST_WITH_FLAGS(UWM_KPROBE_ON_FTRACE | UWM_SP),
0465     TEST_WITH_FLAGS(UWM_KPROBE_ON_FTRACE | UWM_REGS),
0466     TEST_WITH_FLAGS(UWM_KPROBE_ON_FTRACE | UWM_SP | UWM_REGS),
0467     TEST_WITH_FLAGS(UWM_FTRACE),
0468     TEST_WITH_FLAGS(UWM_FTRACE | UWM_SP),
0469     TEST_WITH_FLAGS(UWM_FTRACE | UWM_REGS),
0470     TEST_WITH_FLAGS(UWM_FTRACE | UWM_SP | UWM_REGS),
0471     TEST_WITH_FLAGS(UWM_KRETPROBE),
0472     TEST_WITH_FLAGS(UWM_KRETPROBE | UWM_SP),
0473     TEST_WITH_FLAGS(UWM_KRETPROBE | UWM_REGS),
0474     TEST_WITH_FLAGS(UWM_KRETPROBE | UWM_SP | UWM_REGS),
0475     TEST_WITH_FLAGS(UWM_KRETPROBE_HANDLER),
0476     TEST_WITH_FLAGS(UWM_KRETPROBE_HANDLER | UWM_SP),
0477     TEST_WITH_FLAGS(UWM_KRETPROBE_HANDLER | UWM_REGS),
0478     TEST_WITH_FLAGS(UWM_KRETPROBE_HANDLER | UWM_SP | UWM_REGS),
0479 };
0480 
0481 /*
0482  * Parameter description generator: required for KUNIT_ARRAY_PARAM()
0483  */
0484 static void get_desc(const struct test_params *params, char *desc)
0485 {
0486     strscpy(desc, params->name, KUNIT_PARAM_DESC_SIZE);
0487 }
0488 
0489 /*
0490  * Create test_unwind_gen_params
0491  */
0492 KUNIT_ARRAY_PARAM(test_unwind, param_list, get_desc);
0493 
0494 static void test_unwind_flags(struct kunit *test)
0495 {
0496     struct unwindme u;
0497     const struct test_params *params;
0498 
0499     current_test = test;
0500     params = (const struct test_params *)test->param_value;
0501     u.flags = params->flags;
0502     if (u.flags & UWM_THREAD)
0503         KUNIT_EXPECT_EQ(test, 0, test_unwind_task(&u));
0504     else if (u.flags & UWM_IRQ)
0505         KUNIT_EXPECT_EQ(test, 0, test_unwind_irq(&u));
0506     else
0507         KUNIT_EXPECT_EQ(test, 0, unwindme_func1(&u));
0508 }
0509 
0510 static struct kunit_case unwind_test_cases[] = {
0511     KUNIT_CASE_PARAM(test_unwind_flags, test_unwind_gen_params),
0512     {}
0513 };
0514 
0515 static struct kunit_suite test_unwind_suite = {
0516     .name = "test_unwind",
0517     .test_cases = unwind_test_cases,
0518 };
0519 
0520 kunit_test_suites(&test_unwind_suite);
0521 
0522 MODULE_LICENSE("GPL");