~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/kernel/rethook.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * PowerPC implementation of rethook. This depends on kprobes.
  4  */
  5 
  6 #include <linux/kprobes.h>
  7 #include <linux/rethook.h>
  8 
  9 /*
 10  * Function return trampoline:
 11  *     - init_kprobes() establishes a probepoint here
 12  *     - When the probed function returns, this probe
 13  *         causes the handlers to fire
 14  */
 15 asm(".global arch_rethook_trampoline\n"
 16         ".type arch_rethook_trampoline, @function\n"
 17         "arch_rethook_trampoline:\n"
 18         "nop\n"
 19         "blr\n"
 20         ".size arch_rethook_trampoline, .-arch_rethook_trampoline\n");
 21 
 22 /*
 23  * Called when the probe at kretprobe trampoline is hit
 24  */
 25 static int trampoline_rethook_handler(struct kprobe *p, struct pt_regs *regs)
 26 {
 27         return !rethook_trampoline_handler(regs, regs->gpr[1]);
 28 }
 29 NOKPROBE_SYMBOL(trampoline_rethook_handler);
 30 
 31 void arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mcount)
 32 {
 33         rh->ret_addr = regs->link;
 34         rh->frame = regs->gpr[1];
 35 
 36         /* Replace the return addr with trampoline addr */
 37         regs->link = (unsigned long)arch_rethook_trampoline;
 38 }
 39 NOKPROBE_SYMBOL(arch_rethook_prepare);
 40 
 41 /* This is called from rethook_trampoline_handler(). */
 42 void arch_rethook_fixup_return(struct pt_regs *regs, unsigned long orig_ret_address)
 43 {
 44         /*
 45          * We get here through one of two paths:
 46          * 1. by taking a trap -> kprobe_handler() -> here
 47          * 2. by optprobe branch -> optimized_callback() -> opt_pre_handler() -> here
 48          *
 49          * When going back through (1), we need regs->nip to be setup properly
 50          * as it is used to determine the return address from the trap.
 51          * For (2), since nip is not honoured with optprobes, we instead setup
 52          * the link register properly so that the subsequent 'blr' in
 53          * arch_rethook_trampoline jumps back to the right instruction.
 54          *
 55          * For nip, we should set the address to the previous instruction since
 56          * we end up emulating it in kprobe_handler(), which increments the nip
 57          * again.
 58          */
 59         regs_set_return_ip(regs, orig_ret_address - 4);
 60         regs->link = orig_ret_address;
 61 }
 62 NOKPROBE_SYMBOL(arch_rethook_fixup_return);
 63 
 64 static struct kprobe trampoline_p = {
 65         .addr = (kprobe_opcode_t *) &arch_rethook_trampoline,
 66         .pre_handler = trampoline_rethook_handler
 67 };
 68 
 69 /* rethook initializer */
 70 int __init arch_init_kprobes(void)
 71 {
 72         return register_kprobe(&trampoline_p);
 73 }
 74 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php