hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/arch/arm/probes/kprobes/core.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * arch/arm/kernel/kprobes.c
34 *
....@@ -8,15 +9,6 @@
89 *
910 * Nicolas Pitre <nico@marvell.com>
1011 * Copyright (C) 2007 Marvell Ltd.
11
- *
12
- * This program is free software; you can redistribute it and/or modify
13
- * it under the terms of the GNU General Public License version 2 as
14
- * published by the Free Software Foundation.
15
- *
16
- * This program is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
- * General Public License for more details.
2012 */
2113
2214 #include <linux/kernel.h>
....@@ -239,7 +231,7 @@
239231 * kprobe, and that level is reserved for user kprobe handlers, so we can't
240232 * risk encountering a new kprobe in an interrupt handler.
241233 */
242
-void __kprobes kprobe_handler(struct pt_regs *regs)
234
+static void __kprobes kprobe_handler(struct pt_regs *regs)
243235 {
244236 struct kprobe *p, *cur;
245237 struct kprobe_ctlblk *kcb;
....@@ -288,7 +280,7 @@
288280 /* A nested probe was hit in FIQ, it is a BUG */
289281 pr_warn("Unrecoverable kprobe detected.\n");
290282 dump_kprobe(p);
291
- /* fall through */
283
+ fallthrough;
292284 default:
293285 /* impossible cases */
294286 BUG();
....@@ -421,87 +413,15 @@
421413 /* Called from kretprobe_trampoline */
422414 static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
423415 {
424
- struct kretprobe_instance *ri = NULL;
425
- struct hlist_head *head, empty_rp;
426
- struct hlist_node *tmp;
427
- unsigned long flags, orig_ret_address = 0;
428
- unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
429
- kprobe_opcode_t *correct_ret_addr = NULL;
430
-
431
- INIT_HLIST_HEAD(&empty_rp);
432
- kretprobe_hash_lock(current, &head, &flags);
433
-
434
- /*
435
- * It is possible to have multiple instances associated with a given
436
- * task either because multiple functions in the call path have
437
- * a return probe installed on them, and/or more than one return
438
- * probe was registered for a target function.
439
- *
440
- * We can handle this because:
441
- * - instances are always inserted at the head of the list
442
- * - when multiple return probes are registered for the same
443
- * function, the first instance's ret_addr will point to the
444
- * real return address, and all the rest will point to
445
- * kretprobe_trampoline
446
- */
447
- hlist_for_each_entry_safe(ri, tmp, head, hlist) {
448
- if (ri->task != current)
449
- /* another task is sharing our hash bucket */
450
- continue;
451
-
452
- orig_ret_address = (unsigned long)ri->ret_addr;
453
-
454
- if (orig_ret_address != trampoline_address)
455
- /*
456
- * This is the real return address. Any other
457
- * instances associated with this task are for
458
- * other calls deeper on the call stack
459
- */
460
- break;
461
- }
462
-
463
- kretprobe_assert(ri, orig_ret_address, trampoline_address);
464
-
465
- correct_ret_addr = ri->ret_addr;
466
- hlist_for_each_entry_safe(ri, tmp, head, hlist) {
467
- if (ri->task != current)
468
- /* another task is sharing our hash bucket */
469
- continue;
470
-
471
- orig_ret_address = (unsigned long)ri->ret_addr;
472
- if (ri->rp && ri->rp->handler) {
473
- __this_cpu_write(current_kprobe, &ri->rp->kp);
474
- get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
475
- ri->ret_addr = correct_ret_addr;
476
- ri->rp->handler(ri, regs);
477
- __this_cpu_write(current_kprobe, NULL);
478
- }
479
-
480
- recycle_rp_inst(ri, &empty_rp);
481
-
482
- if (orig_ret_address != trampoline_address)
483
- /*
484
- * This is the real return address. Any other
485
- * instances associated with this task are for
486
- * other calls deeper on the call stack
487
- */
488
- break;
489
- }
490
-
491
- kretprobe_hash_unlock(current, &flags);
492
-
493
- hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
494
- hlist_del(&ri->hlist);
495
- kfree(ri);
496
- }
497
-
498
- return (void *)orig_ret_address;
416
+ return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline,
417
+ (void *)regs->ARM_fp);
499418 }
500419
501420 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
502421 struct pt_regs *regs)
503422 {
504423 ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr;
424
+ ri->fp = (void *)regs->ARM_fp;
505425
506426 /* Replace the return addr with trampoline addr. */
507427 regs->ARM_lr = (unsigned long)&kretprobe_trampoline;