Commit 3b7d14e9 authored by Marc Zyngier's avatar Marc Zyngier Committed by Catalin Marinas

arm64: kprobes: Cleanup jprobe_return

jprobe_return seems to have aged badly. Comments referring to
non-existent behaviours, and a dangerous habit of messing
with registers without telling the compiler.

This patches applies the following remedies:
- Fix the comments to describe the actual behaviour
- Tidy up the asm sequence to directly assign the
  stack pointer without clobbering extra registers
- Mark the rest of the function as unreachable() so
  that the compiler knows that there is no need for
  an epilogue
- Stop making jprobe_return_break a global function
  (you really don't want to call that guy, and it isn't
  even a function).

Tested with tcp_probe.
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent ab4c1325
...@@ -34,8 +34,6 @@ ...@@ -34,8 +34,6 @@
#include "decode-insn.h" #include "decode-insn.h"
void jprobe_return_break(void);
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
...@@ -516,18 +514,17 @@ void __kprobes jprobe_return(void) ...@@ -516,18 +514,17 @@ void __kprobes jprobe_return(void)
/* /*
* Jprobe handler return by entering break exception, * Jprobe handler return by entering break exception,
* encoded same as kprobe, but with following conditions * encoded same as kprobe, but with following conditions
* -a magic number in x0 to identify from rest of other kprobes. * -a special PC to identify it from the other kprobes.
* -restore stack addr to original saved pt_regs * -restore stack addr to original saved pt_regs
*/ */
asm volatile ("ldr x0, [%0]\n\t" asm volatile(" mov sp, %0 \n"
"mov sp, x0\n\t" "jprobe_return_break: brk %1 \n"
".globl jprobe_return_break\n\t" :
"jprobe_return_break:\n\t" : "r" (kcb->jprobe_saved_regs.sp),
"brk %1\n\t" "I" (BRK64_ESR_KPROBES)
: : "memory");
: "r"(&kcb->jprobe_saved_regs.sp),
"I"(BRK64_ESR_KPROBES) unreachable();
: "memory");
} }
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
...@@ -536,6 +533,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) ...@@ -536,6 +533,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
long stack_addr = kcb->jprobe_saved_regs.sp; long stack_addr = kcb->jprobe_saved_regs.sp;
long orig_sp = kernel_stack_pointer(regs); long orig_sp = kernel_stack_pointer(regs);
struct jprobe *jp = container_of(p, struct jprobe, kp); struct jprobe *jp = container_of(p, struct jprobe, kp);
extern const char jprobe_return_break[];
if (instruction_pointer(regs) != (u64) jprobe_return_break) if (instruction_pointer(regs) != (u64) jprobe_return_break)
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment