Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/ftrace: Implement raw syscall tracepoints on PowerPC

This patch implements the raw syscall tracepoints on PowerPC and exports
them for ftrace syscalls to use.

To minimise reworking existing code, I slightly re-ordered the thread
info flags such that the new TIF_SYSCALL_TRACEPOINT bit would still fit
within the 16 bits of the andi. instruction's UI field. The instructions
in question are in /arch/powerpc/kernel/entry_{32,64}.S to and the
_TIF_SYSCALL_T_OR_A with the thread flags to see if system call tracing
is enabled.

In the case of 64bit PowerPC, arch_syscall_addr and
arch_syscall_match_sym_name are overridden to allow ftrace syscalls to
work given the unusual system call table structure and symbol names that
start with a period.

Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

authored by

Ian Munsie and committed by
Benjamin Herrenschmidt
02424d89 3f5785ec

+44 -2
+1
arch/powerpc/Kconfig
··· 141 141 select GENERIC_IRQ_SHOW 142 142 select GENERIC_IRQ_SHOW_LEVEL 143 143 select HAVE_RCU_TABLE_FREE if SMP 144 + select HAVE_SYSCALL_TRACEPOINTS 144 145 145 146 config EARLY_PRINTK 146 147 bool
+14
arch/powerpc/include/asm/ftrace.h
··· 60 60 61 61 #endif 62 62 63 + #if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__) 64 + #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME 65 + static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) 66 + { 67 + /* 68 + * Compare the symbol name with the system call name. Skip the .sys or .SyS 69 + * prefix from the symbol name and the sys prefix from the system call name and 70 + * just match the rest. This is only needed on ppc64 since symbol names on 71 + * 32bit do not start with a period so the generic function will work. 72 + */ 73 + return !strcmp(sym + 4, name + 3); 74 + } 75 + #endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 && !__ASSEMBLY__ */ 76 + 63 77 #endif /* _ASM_POWERPC_FTRACE */
+5
arch/powerpc/include/asm/syscall.h
··· 15 15 16 16 #include <linux/sched.h> 17 17 18 + /* ftrace syscalls requires exporting the sys_call_table */ 19 + #ifdef CONFIG_FTRACE_SYSCALLS 20 + extern const unsigned long *sys_call_table; 21 + #endif /* CONFIG_FTRACE_SYSCALLS */ 22 + 18 23 static inline long syscall_get_nr(struct task_struct *task, 19 24 struct pt_regs *regs) 20 25 {
+5 -2
arch/powerpc/include/asm/thread_info.h
··· 110 110 #define TIF_NOERROR 12 /* Force successful syscall return */ 111 111 #define TIF_NOTIFY_RESUME 13 /* callback before returning to user */ 112 112 #define TIF_FREEZE 14 /* Freezing for suspend */ 113 - #define TIF_RUNLATCH 15 /* Is the runlatch enabled? */ 113 + #define TIF_SYSCALL_TRACEPOINT 15 /* syscall tracepoint instrumentation */ 114 + #define TIF_RUNLATCH 16 /* Is the runlatch enabled? */ 114 115 115 116 /* as above, but as bit values */ 116 117 #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) ··· 128 127 #define _TIF_NOERROR (1<<TIF_NOERROR) 129 128 #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) 130 129 #define _TIF_FREEZE (1<<TIF_FREEZE) 130 + #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) 131 131 #define _TIF_RUNLATCH (1<<TIF_RUNLATCH) 132 - #define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP) 132 + #define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ 133 + _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT) 133 134 134 135 #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ 135 136 _TIF_NOTIFY_RESUME)
+1
arch/powerpc/kernel/Makefile
··· 109 109 110 110 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 111 111 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 112 + obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o 112 113 obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o 113 114 114 115 obj-$(CONFIG_PPC_PERF_CTRS) += perf_event.o
+8
arch/powerpc/kernel/ftrace.c
··· 22 22 #include <asm/cacheflush.h> 23 23 #include <asm/code-patching.h> 24 24 #include <asm/ftrace.h> 25 + #include <asm/syscall.h> 25 26 26 27 27 28 #ifdef CONFIG_DYNAMIC_FTRACE ··· 601 600 } 602 601 } 603 602 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 603 + 604 + #if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) 605 + unsigned long __init arch_syscall_addr(int nr) 606 + { 607 + return sys_call_table[nr*2]; 608 + } 609 + #endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 */
+10
arch/powerpc/kernel/ptrace.c
··· 29 29 #include <linux/signal.h> 30 30 #include <linux/seccomp.h> 31 31 #include <linux/audit.h> 32 + #include <trace/syscall.h> 32 33 #ifdef CONFIG_PPC32 33 34 #include <linux/module.h> 34 35 #endif ··· 40 39 #include <asm/page.h> 41 40 #include <asm/pgtable.h> 42 41 #include <asm/system.h> 42 + 43 + #define CREATE_TRACE_POINTS 44 + #include <trace/events/syscalls.h> 43 45 44 46 /* 45 47 * The parameter save area on the stack is used to store arguments being passed ··· 1714 1710 */ 1715 1711 ret = -1L; 1716 1712 1713 + if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) 1714 + trace_sys_enter(regs, regs->gpr[0]); 1715 + 1717 1716 if (unlikely(current->audit_context)) { 1718 1717 #ifdef CONFIG_PPC64 1719 1718 if (!is_32bit_task()) ··· 1744 1737 if (unlikely(current->audit_context)) 1745 1738 audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, 1746 1739 regs->result); 1740 + 1741 + if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) 1742 + trace_sys_exit(regs, regs->result); 1747 1743 1748 1744 step = test_thread_flag(TIF_SINGLESTEP); 1749 1745 if (step || test_thread_flag(TIF_SYSCALL_TRACE))