diff options
| author | Marc Zyngier <marc.zyngier@arm.com> | 2016-07-21 09:44:17 +0100 |
|---|---|---|
| committer | Alex Shi <alex.shi@linaro.org> | 2016-10-20 15:38:13 +0800 |
| commit | a5d55dd10f2a061849e7a665aa4b16bf258d9d0a (patch) | |
| tree | 1793b968dfc363f5a370ac75b9a16f823063bf97 | |
| parent | 71b5200f5f0c1e9966dd7d238526e85f4fbf8089 (diff) | |
arm64: kprobes: Cleanup jprobe_return
commit 3b7d14e9f3f1efd4c4348800e977fd1ce4ca660e upstream.
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: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: David A. Long <dave.long@linaro.org>
| -rw-r--r-- | arch/arm64/kernel/probes/kprobes.c | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index b1189741dbb0..235455412caa 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c @@ -34,8 +34,6 @@ #include "decode-insn.h" -void jprobe_return_break(void); - DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); @@ -513,18 +511,17 @@ void __kprobes jprobe_return(void) /* * Jprobe handler return by entering break exception, * 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 */ - asm volatile ("ldr x0, [%0]\n\t" - "mov sp, x0\n\t" - ".globl jprobe_return_break\n\t" - "jprobe_return_break:\n\t" - "brk %1\n\t" - : - : "r"(&kcb->jprobe_saved_regs.sp), - "I"(BRK64_ESR_KPROBES) - : "memory"); + asm volatile(" mov sp, %0 \n" + "jprobe_return_break: brk %1 \n" + : + : "r" (kcb->jprobe_saved_regs.sp), + "I" (BRK64_ESR_KPROBES) + : "memory"); + + unreachable(); } int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) @@ -533,6 +530,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) long stack_addr = kcb->jprobe_saved_regs.sp; long orig_sp = kernel_stack_pointer(regs); struct jprobe *jp = container_of(p, struct jprobe, kp); + extern const char jprobe_return_break[]; if (instruction_pointer(regs) != (u64) jprobe_return_break) return 0; |
