powerpc: Consolidate *probe definitions
PATCH 1/3 powerpc: Consolidate *probe definitions
From: Ananth N Mavinakayanahalli <[email protected]>
Move is_trap() and relatives to a common file to be shared between *probes. Code movement only; no change in functionality.
Suggested by Michael Ellerman.
--- arch/powerpc/include/asm/kprobes.h | 15 +------------ arch/powerpc/include/asm/probes.h | 42 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 13 deletions(-)
arch/powerpc/include/asm/kprobes.h +2 -13
@@ -29,21 +29,16 @@#include <linux/types.h> #include <linux/ptrace.h> #include <linux/percpu.h> +#include <asm/probes.h> #define __ARCH_WANT_KPROBES_INSN_SLOTstruct pt_regs ;struct kprobe ; -typedef unsigned int kprobe_opcode_t ; -#define BREAKPOINT_INSTRUCTION 0x7fe00008/* trap */ +typedef opcode_t kprobe_opcode_t ;#define MAX_INSN_SIZE 1 -#define IS_TW (instr) (((instr) & 0xfc0007fe) == 0x7c000008) -#define IS_TD (instr) (((instr) & 0xfc0007fe) == 0x7c000088) -#define IS_TDI (instr) (((instr) & 0xfc000000) == 0x08000000) -#define IS_TWI (instr) (((instr) & 0xfc000000) == 0x0c000000) -#ifdef CONFIG_PPC64 /* * 64bit powerpc uses function descriptors.
@@ -72,12 +67,6 @@ typedef unsigned int kprobe_opcode_t; addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name); \ } \ } - -#define is_trap (instr) (IS_TW(instr) || IS_TD(instr) || \ - IS_TWI(instr) || IS_TDI(instr)) -#else -/* Use stock kprobe_lookup_name since ppc32 doesn't use function descriptors */ -#define is_trap (instr) (IS_TW(instr) || IS_TWI(instr))#endif #define flush_insn_slot (p) do { } while (0)
arch/powerpc/include/asm/probes.h new file +42 -0
42 lines not on this page · raw message
PATCH 2/3 powerpc: Add trap_nr to thread_struct
From: Ananth N Mavinakayanahalli <[email protected]>
Add thread_struct.trap_nr and use it to store the last exception the thread experienced. In this patch, we populate the field at various places where we force_sig_info() to the process.
This is also used in uprobes to determine if the probed instruction caused an exception.
--- arch/powerpc/include/asm/processor.h | 1 + arch/powerpc/kernel/process.c | 2 ++ arch/powerpc/kernel/traps.c | 1 + arch/powerpc/mm/fault.c | 1 + 4 files changed, 5 insertions(+)
arch/powerpc/include/asm/processor.h +1 -0
@@ -219,6 +219,7 @@ struct thread_struct {#endif /* CONFIG_HAVE_HW_BREAKPOINT */ #endif unsigned long dabr;/* Data address breakpoint register */ +unsigned long trap_nr;/* last trap # on this thread */ #ifdef CONFIG_ALTIVEC /* Complete AltiVec register set */ vector128 vr[32] __attribute__((aligned(16)));
arch/powerpc/kernel/process.c +2 -0
@@ -258,6 +258,7 @@ void do_send_trap(struct pt_regs *regs, {siginfo_t info; + current->thread.trap_nr = signal_code;if (notify_die (DIE_DABR_MATCH ,"dabr_match" , regs, error_code,11 ,SIGSEGV ) ==NOTIFY_STOP )return ;
@@ -275,6 +276,7 @@ void do_dabr(struct pt_regs *regs, unsig {siginfo_t info; + current->thread.trap_nr =TRAP_HWBKPT ;if (notify_die (DIE_DABR_MATCH ,"dabr_match" , regs, error_code,11 ,SIGSEGV ) ==NOTIFY_STOP )return ;
arch/powerpc/kernel/traps.c +1 -0
@@ -251,6 +251,7 @@ void _exception(int signr, struct pt_regif (arch_irqs_disabled () && !arch_irq_disabled_regs (regs))local_irq_enable (); + current->thread.trap_nr = code;memset (&info,0 ,sizeof (info)); info.si_signo = signr; info.si_code = code;
arch/powerpc/mm/fault.c +1 -0
@@ -133,6 +133,7 @@ static int do_sigbus(struct pt_regs *regup_read (¤t->mm->mmap_sem);if (user_mode (regs)) { + current->thread.trap_nr =BUS_ADRERR ; info.si_signo =SIGBUS ; info.si_errno =0 ; info.si_code =BUS_ADRERR ;
PATCH v5 3/3 powerpc: Uprobes port to powerpc
In reply to Ananth N MavinakayanahalliFrom: Ananth N Mavinakayanahalli <[email protected]>
This is the port of uprobes to powerpc. Usage is similar to x86.
[root@xxxx ~]# ./bin/perf probe -x /lib64/libc.so.6 malloc Added new event:
probe_libc:malloc (on 0xb4860)
You can now use it in all perf tools, such as:
perf record -e probe_libc:malloc -aR sleep 1
[root@xxxx ~]# ./bin/perf record -e probe_libc:malloc -aR sleep 20 [ perf record: Woken up 22 times to write data ]
[ perf record: Captured and wrote 5.843 MB perf.data (~255302 samples) ] [root@xxxx ~]# ./bin/perf report --stdio
...
# Samples: 83K of event 'probe_libc:malloc'
# Event count (approx.): 83484
#
# Overhead Command Shared Object Symbol
# ........ ............ ............. ..........
#
69.05% tar libc-2.12.so [.] malloc
28.57% rm libc-2.12.so [.] malloc
1.32% avahi-daemon libc-2.12.so [.] malloc
0.58% bash libc-2.12.so [.] malloc
0.28% sshd libc-2.12.so [.] malloc
0.08% irqbalance libc-2.12.so [.] malloc
0.05% bzip2 libc-2.12.so [.] malloc
0.04% sleep libc-2.12.so [.] malloc
0.03% multipathd libc-2.12.so [.] malloc
0.01% sendmail libc-2.12.so [.] malloc
0.01% automount libc-2.12.so [.] mallocThe trap_nr addition patch is a prereq.
---
Tested on POWER6; I don't see anything here that should stop it from working on a ppc32; since I don't have access to a ppc32 machine, it would be good if somoene could verify that part.
TODO:
Testsuite for uprobes (Not powerpc specific).
V5:
a. Incorporated Oleg's suggestion to make arch_uprobe a union for
easier deref of u32 on powerpc.
b. Incorporated various review comments by Michael Ellerman and
Benjamin Herrenschmidt.
V4:
Enhance arch_analyze_uprobe_insn() to reject uprobes on trap variants.
V3:
Added abort_xol() logic for powerpc, using thread_struct.trap_nr to determine if the stepped instruction caused an exception.
V2:
a. arch_uprobe_analyze_insn() now gets unsigned long addr. b. Verified that mtmsr[d] and rfi[d] are handled correctly by
emulate_step() (no changes to this patch).
arch/powerpc/Kconfig | 3 arch/powerpc/include/asm/thread_info.h | 4 arch/powerpc/include/asm/uprobes.h | 55 +++++++++ arch/powerpc/kernel/Makefile | 1 arch/powerpc/kernel/signal.c | 6 + arch/powerpc/kernel/uprobes.c | 184 +++++++++++++++++++++++++++++++++ 6 files changed, 252 insertions(+), 1 deletion(-)
arch/powerpc/include/asm/thread_info.h +3 -1
@@ -102,6 +102,7 @@ static inline struct thread_info *curren#define TIF_RESTOREALL 11/* Restore all regs (implies NOERROR) */ #define TIF_NOERROR 12/* Force successful syscall return */ #define TIF_NOTIFY_RESUME 13/* callback before returning to user */ +#define TIF_UPROBE 14/* breakpointed or single-stepping */ #define TIF_SYSCALL_TRACEPOINT 15/* syscall tracepoint instrumentation */ /* as above, but as bit values */
@@ -118,12 +119,13 @@ static inline struct thread_info *curren#define _TIF_RESTOREALL (1<<TIF_RESTOREALL)#define _TIF_NOERROR (1<<TIF_NOERROR)#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) +#define _TIF_UPROBE (1<<TIF_UPROBE)#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT)#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ - _TIF_NOTIFY_RESUME) + _TIF_NOTIFY_RESUME | _TIF_UPROBE)#define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR)/* Bits in local_flags */
arch/powerpc/include/asm/uprobes.h new file +55 -0
55 lines not on this page · raw message
arch/powerpc/kernel/Makefile +1 -0
@@ -96,6 +96,7 @@ obj-$(CONFIG_MODULES) += ppc_ksyms.o obj-$(CONFIG_BOOTX_TEXT) += btext.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_KPROBES) += kprobes.o +obj-$(CONFIG_UPROBES) += uprobes.o obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_SWIOTLB) += dma-swiotlb.o
arch/powerpc/kernel/signal.c +6 -0
@@ -11,6 +11,7 @@#include <linux/tracehook.h> #include <linux/signal.h> +#include <linux/uprobes.h> #include <linux/key.h> #include <asm/hw_breakpoint.h> #include <asm/uaccess.h>
@@ -157,6 +158,11 @@ static int do_signal(struct pt_regs *regvoid do_notify_resume (struct pt_regs *regs,unsigned long thread_info_flags) { +if (thread_info_flags & _TIF_UPROBE) { +clear_thread_flag (TIF_UPROBE ); +uprobe_notify_resume (regs); + } +if (thread_info_flags & _TIF_SIGPENDING)do_signal (regs);
arch/powerpc/kernel/uprobes.c new file +184 -0
184 lines not on this page · raw message
arch/powerpc/Kconfig +3 -0
@@ -239,6 +239,9 @@ config PPC_OF_PLATFORM_PCI config ARCH_SUPPORTS_DEBUG_PAGEALLOC def_bool y +config ARCH_SUPPORTS_UPROBES + def_bool y + config PPC_ADV_DEBUG_REGS bool depends on 40x || BOOKE
Re: [PATCH v5 3/3] powerpc: Uprobes port to powerpc
Quoted 3 lines · Ananth N Mavinakayanahalli
From: Ananth N Mavinakayanahalli <[email protected]>
This is the port of uprobes to powerpc. Usage is similar to x86.
Guys, can you do a minimum of build testing ?
This one breaks due to uprobe_get_swbp_addr() being defined in both asm and include/linux when CONFIG_UPROBE isn't set. You don't need to define it at all in fact, the generic code takes care of both the declaration for CONFIG_UPROBE and the empty inline for !CONFIG_UPROBE.
I'm fixing that one up myself but please, please, get yourself a test build script or something to make sure you don't at least break the build when the stuff you're adding isn't enabled (among others).
Cheers,
Ben.
Re: [PATCH v5 3/3] powerpc: Uprobes port to powerpc
Quoted 7 lines · Benjamin Herrenschmidt
Quoted 3 lines · Ananth N Mavinakayanahalli
From: Ananth N Mavinakayanahalli <[email protected]>
This is the port of uprobes to powerpc. Usage is similar to x86.
Guys, can you do a minimum of build testing ?
Quoted 8 lines
This one breaks due to
uprobe_get_swbp_addr()being defined in both asm andinclude/linuxwhenCONFIG_UPROBEisn't set. You don't need to define it at all in fact, the generic code takes care of both the declaration forCONFIG_UPROBEand the empty inline for !CONFIG_UPROBE.I'm fixing that one up myself but please, please, get yourself a test build script or something to make sure you don't at least break the build when the stuff you're adding isn't enabled (among others).
Sorry Ben. That was an oversight. Won't happen again.
Regards,
Ananth