powerpc: perf hardware breakpoint fixes
cover powerpc: perf hardware breakpoint fixes
Here are a couple of patches for perf for hardware breakpoints. Along with https://lkml.org/lkml/2012/8/16/5 hardware breakpoints now work for me powerpc. These patches don't depend on that patch though.
Michael Neuling (2):
powerpc: Remove unessasary ifdefs
powerpc: Fix null pointer deref in perf hardware breakpoints
arch/powerpc/include/asm/cputable.h | 2 -- arch/powerpc/kernel/hw_breakpoint.c | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-)
Signature · 1 line
1.7.9.5
PATCH 1/1 powerpc: Remove unnecessary ifdefs
--- arch/powerpc/include/asm/cputable.h | 2 -- 1 file changed, 2 deletions(-)
arch/powerpc/include/asm/cputable.h +0 -2
@@ -553,9 +553,7 @@ static inline int cpu_has_feature(unsigned long feature) & feature); } -#ifdef CONFIG_HAVE_HW_BREAKPOINT #define HBP_NUM 1 -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ #endif /* !__ASSEMBLY__ */
Signature · 1 line
1.7.9.5
PATCH 1/1 powerpc: Fix null pointer deref in perf hardware breakpoints
In reply to Michael NeulingCurrently if you are doing a global perf recording with hardware breakpoints (ie perf record -e mem:0xdeadbeef -a), you can oops with:
Faulting instruction address: 0xc000000000738890 cpu 0xc: Vector: 300 (Data Access) at [c0000003f76af8d0]
pc: c000000000738890: .hw_breakpoint_handler+0xa0/0x1e0
lr: c000000000738830: .hw_breakpoint_handler+0x40/0x1e0
sp: c0000003f76afb50
msr: 8000000000001032
dar: 6f0
dsisr: 42000000
current = 0xc0000003f765ac00
paca = 0xc00000000f262a00 softe: 0 irq_happened: 0x01
pid = 6810, comm = loop-read enter ? for help
[c0000003f76afbe0] c00000000073cd04 .notifier_call_chain.isra.0+0x84/0xe0 [c0000003f76afc80] c00000000073cdbc .notify_die+0x3c/0x60 [c0000003f76afd20] c0000000000139f0 .do_dabr+0x40/0xf0 [c0000003f76afe30] c000000000005a9c handle_dabr_fault+0x14/0x48 --- Exception: 300 (Data Access) at 0000000010000480
SP (ff8679e0) is in userspace
This is because we don't check to see if the break point is associated with task before we deference the task_struct pointer. This checks pointer before dereferencing it.
--- arch/powerpc/kernel/hw_breakpoint.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/powerpc/kernel/hw_breakpoint.c +2 -1
@@ -253,7 +253,8 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)/* Do not emulate user-space instructions, instead single-step them */ if (user_mode (regs)) { - bp->ctx->task->thread.last_hit_ubp = bp; +if (bp->ctx->task) + bp->ctx->task->thread.last_hit_ubp = bp; regs->msr |=MSR_SE ; goto out; }
Signature · 1 line
1.7.9.5
PATCH 1/1 powerpc: Fix null pointer deref in perf hardware breakpoints
Currently if you are doing a global perf recording with hardware breakpoints (ie perf record -e mem:0xdeadbeef -a), you can oops with:
Faulting instruction address: 0xc000000000738890 cpu 0xc: Vector: 300 (Data Access) at [c0000003f76af8d0]
pc: c000000000738890: .hw_breakpoint_handler+0xa0/0x1e0
lr: c000000000738830: .hw_breakpoint_handler+0x40/0x1e0
sp: c0000003f76afb50
msr: 8000000000001032
dar: 6f0
dsisr: 42000000
current = 0xc0000003f765ac00
paca = 0xc00000000f262a00 softe: 0 irq_happened: 0x01
pid = 6810, comm = loop-read enter ? for help
[c0000003f76afbe0] c00000000073cd04 .notifier_call_chain.isra.0+0x84/0xe0 [c0000003f76afc80] c00000000073cdbc .notify_die+0x3c/0x60 [c0000003f76afd20] c0000000000139f0 .do_dabr+0x40/0xf0 [c0000003f76afe30] c000000000005a9c handle_dabr_fault+0x14/0x48 --- Exception: 300 (Data Access) at 0000000010000480
SP (ff8679e0) is in userspace
This is because we don't check to see if the break point is associated with task before we deference the task_struct pointer.
This changes the update to use current.
---
v2: mpe pointed out that we should be using current here so that once we single step the next instruction, we know where to store the perf event. Confirming this, the original patch didn't actually record any data when we used -a even when we hit.
This new patch fixes this so that -a doesn't oops and records data too!
arch/powerpc/kernel/hw_breakpoint.c +1 -1
@@ -253,7 +253,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)/* Do not emulate user-space instructions, instead single-step them */ if (user_mode (regs)) { - bp->ctx->task->thread.last_hit_ubp = bp; + current->thread.last_hit_ubp = bp; regs->msr |=MSR_SE ; goto out; }