aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/probes
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2016-07-21 04:44:17 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2016-07-21 06:47:52 -0400
commit3b7d14e9f3f1efd4c4348800e977fd1ce4ca660e (patch)
tree60fd0adbd3de143dc45d8fd6f8f2852b6ccd9019 /arch/arm64/kernel/probes
parentab4c1325d4bf111a590a1f773e3d93bde7f40201 (diff)
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: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/probes')
-rw-r--r--arch/arm64/kernel/probes/kprobes.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
index 09f8ae98da5a..973c15df5211 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -34,8 +34,6 @@
34 34
35#include "decode-insn.h" 35#include "decode-insn.h"
36 36
37void jprobe_return_break(void);
38
39DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 37DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
40DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 38DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
41 39
@@ -516,18 +514,17 @@ void __kprobes jprobe_return(void)
516 /* 514 /*
517 * Jprobe handler return by entering break exception, 515 * Jprobe handler return by entering break exception,
518 * encoded same as kprobe, but with following conditions 516 * encoded same as kprobe, but with following conditions
519 * -a magic number in x0 to identify from rest of other kprobes. 517 * -a special PC to identify it from the other kprobes.
520 * -restore stack addr to original saved pt_regs 518 * -restore stack addr to original saved pt_regs
521 */ 519 */
522 asm volatile ("ldr x0, [%0]\n\t" 520 asm volatile(" mov sp, %0 \n"
523 "mov sp, x0\n\t" 521 "jprobe_return_break: brk %1 \n"
524 ".globl jprobe_return_break\n\t" 522 :
525 "jprobe_return_break:\n\t" 523 : "r" (kcb->jprobe_saved_regs.sp),
526 "brk %1\n\t" 524 "I" (BRK64_ESR_KPROBES)
527 : 525 : "memory");
528 : "r"(&kcb->jprobe_saved_regs.sp), 526
529 "I"(BRK64_ESR_KPROBES) 527 unreachable();
530 : "memory");
531} 528}
532 529
533int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) 530int __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 long stack_addr = kcb->jprobe_saved_regs.sp; 533 long stack_addr = kcb->jprobe_saved_regs.sp;
537 long orig_sp = kernel_stack_pointer(regs); 534 long orig_sp = kernel_stack_pointer(regs);
538 struct jprobe *jp = container_of(p, struct jprobe, kp); 535 struct jprobe *jp = container_of(p, struct jprobe, kp);
536 extern const char jprobe_return_break[];
539 537
540 if (instruction_pointer(regs) != (u64) jprobe_return_break) 538 if (instruction_pointer(regs) != (u64) jprobe_return_break)
541 return 0; 539 return 0;