From ef18272453c97238fc9a89211d4c609ef9c760dc Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Sat, 22 Dec 2012 00:21:10 -0500 Subject: [PATCH 01/11] arch/tile: Call tracehook_report_syscall_{entry,exit} in syscall trace Call tracehook functions for syscall tracing. The check for TIF_SYSCALL_TRACE was removed, because the same check is done right before in the assembly file. Signed-off-by: Simon Marchi Signed-off-by: Chris Metcalf [with ptrace.h fixup] --- arch/tile/include/asm/ptrace.h | 3 ++- arch/tile/kernel/intvec_32.S | 10 ++++++++-- arch/tile/kernel/intvec_64.S | 10 ++++++++-- arch/tile/kernel/ptrace.c | 32 +++++++++++--------------------- 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h index 2e83fc1b9467..fd412260aff7 100644 --- a/arch/tile/include/asm/ptrace.h +++ b/arch/tile/include/asm/ptrace.h @@ -44,7 +44,8 @@ typedef unsigned long pt_reg_t; struct pt_regs *get_pt_regs(struct pt_regs *); /* Trace the current syscall. */ -extern void do_syscall_trace(void); +extern int do_syscall_trace_enter(struct pt_regs *regs); +extern void do_syscall_trace_exit(struct pt_regs *regs); #define arch_has_single_step() (1) diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index f212bf7cea86..cb52d66343ed 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S @@ -1201,7 +1201,10 @@ handle_syscall: lw r30, r31 andi r30, r30, _TIF_SYSCALL_TRACE bzt r30, .Lrestore_syscall_regs - jal do_syscall_trace + { + PTREGS_PTR(r0, PTREGS_OFFSET_BASE) + jal do_syscall_trace_enter + } FEEDBACK_REENTER(handle_syscall) /* @@ -1252,7 +1255,10 @@ handle_syscall: lw r30, r31 andi r30, r30, _TIF_SYSCALL_TRACE bzt r30, 1f - jal do_syscall_trace + { + PTREGS_PTR(r0, PTREGS_OFFSET_BASE) + jal do_syscall_trace_exit + } FEEDBACK_REENTER(handle_syscall) 1: { movei r30, 0 /* not an NMI */ diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S index 4ea080902654..21991f72eba3 100644 --- a/arch/tile/kernel/intvec_64.S +++ b/arch/tile/kernel/intvec_64.S @@ -1006,7 +1006,10 @@ handle_syscall: addi r30, r31, THREAD_INFO_STATUS_OFFSET - THREAD_INFO_FLAGS_OFFSET beqzt r30, .Lrestore_syscall_regs } - jal do_syscall_trace + { + PTREGS_PTR(r0, PTREGS_OFFSET_BASE) + jal do_syscall_trace_enter + } FEEDBACK_REENTER(handle_syscall) /* @@ -1077,7 +1080,10 @@ handle_syscall: andi r0, r30, _TIF_SINGLESTEP beqzt r0, 1f } - jal do_syscall_trace + { + PTREGS_PTR(r0, PTREGS_OFFSET_BASE) + jal do_syscall_trace_exit + } FEEDBACK_REENTER(handle_syscall) andi r0, r30, _TIF_SINGLESTEP diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c index 9835312d5a91..0ab8b76baddc 100644 --- a/arch/tile/kernel/ptrace.c +++ b/arch/tile/kernel/ptrace.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -246,29 +247,18 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, } #endif -void do_syscall_trace(void) +int do_syscall_trace_enter(struct pt_regs *regs) { - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; - - if (!(current->ptrace & PT_PTRACED)) - return; - - /* - * The 0x80 provides a way for the tracing parent to distinguish - * between a syscall stop and SIGTRAP delivery - */ - ptrace_notify(SIGTRAP|((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); - - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; + if (tracehook_report_syscall_entry(regs)) { + regs->regs[TREG_SYSCALL_NR] = -1; } + + return regs->regs[TREG_SYSCALL_NR]; +} + +void do_syscall_trace_exit(struct pt_regs *regs) +{ + tracehook_report_syscall_exit(regs, 0); } void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) From 969f6fe6fc5ecc7a2edcc34f29b7f05fcf982266 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Sat, 22 Dec 2012 00:21:12 -0500 Subject: [PATCH 02/11] arch/tile: Enable HAVE_ARCH_TRACEHOOK Looks like we have everything needed for that. Signed-off-by: Simon Marchi Signed-off-by: Chris Metcalf --- arch/tile/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 25877aebc685..e911ef638b77 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -22,6 +22,7 @@ config TILE select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_CLOCKEVENTS select MODULES_USE_ELF_RELA + select HAVE_ARCH_TRACEHOOK # FIXME: investigate whether we need/want these options. # select HAVE_IOREMAP_PROT From e2ed522aaad79db339cecbbc4ae2a0d422ee4c4f Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Mon, 21 Jan 2013 19:54:55 -0500 Subject: [PATCH 03/11] tile: move declaration of sys_call_table to When activating syscall tracing, kernel/trace/trace_syscalls.c doesn't find sys_call_table because it includes , not . Also, looking at the other architectures, that is probably where it should be. Signed-off-by: Simon Marchi Signed-off-by: Chris Metcalf --- arch/tile/include/asm/syscall.h | 6 ++++++ arch/tile/include/asm/syscalls.h | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/tile/include/asm/syscall.h b/arch/tile/include/asm/syscall.h index d35e0dcb67b1..9644b88f133d 100644 --- a/arch/tile/include/asm/syscall.h +++ b/arch/tile/include/asm/syscall.h @@ -22,6 +22,12 @@ #include #include +/* The array of function pointers for syscalls. */ +extern void *sys_call_table[]; +#ifdef CONFIG_COMPAT +extern void *compat_sys_call_table[]; +#endif + /* * Only the low 32 bits of orig_r0 are meaningful, so we return int. * This importantly ignores the high bits on 64-bit, so comparisons diff --git a/arch/tile/include/asm/syscalls.h b/arch/tile/include/asm/syscalls.h index 78886e2417a6..07b298450ef2 100644 --- a/arch/tile/include/asm/syscalls.h +++ b/arch/tile/include/asm/syscalls.h @@ -24,12 +24,6 @@ #include #include -/* The array of function pointers for syscalls. */ -extern void *sys_call_table[]; -#ifdef CONFIG_COMPAT -extern void *compat_sys_call_table[]; -#endif - /* * Note that by convention, any syscall which requires the current * register set takes an additional "struct pt_regs *" pointer; a From 6e4a2f7f94cbac4e1f111f604ccf57dcbdef0a81 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Mon, 21 Jan 2013 19:54:56 -0500 Subject: [PATCH 04/11] tile: Add definition of NR_syscalls It is required by the syscall tracepoint mechanism. Signed-off-by: Simon Marchi Signed-off-by: Chris Metcalf --- arch/tile/include/uapi/asm/unistd.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/tile/include/uapi/asm/unistd.h b/arch/tile/include/uapi/asm/unistd.h index cd7b6dd9d471..3866397aaf5a 100644 --- a/arch/tile/include/uapi/asm/unistd.h +++ b/arch/tile/include/uapi/asm/unistd.h @@ -20,6 +20,8 @@ /* Use the standard ABI for syscalls. */ #include +#define NR_syscalls __NR_syscalls + /* Additional Tilera-specific syscalls. */ #define __NR_cacheflush (__NR_arch_specific_syscall + 1) __SYSCALL(__NR_cacheflush, sys_cacheflush) From ef567f25d5d9d803b89bc2aec6bb71fe8b4bebd9 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Mon, 21 Jan 2013 19:54:57 -0500 Subject: [PATCH 05/11] tile: support TIF_SYSCALL_TRACEPOINT; select HAVE_SYSCALL_TRACEPOINTS This patch adds support for the TIF_SYSCALL_TRACEPOINT on the tile architecture. Basically, it calls the appropriate tracepoints on syscall entry and exit. Signed-off-by: Simon Marchi Signed-off-by: Chris Metcalf --- arch/tile/Kconfig | 1 + arch/tile/include/asm/thread_info.h | 8 ++++++++ arch/tile/kernel/intvec_64.S | 14 ++++++++++---- arch/tile/kernel/ptrace.c | 17 ++++++++++++++--- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index e911ef638b77..0e500d90c2a0 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -23,6 +23,7 @@ config TILE select GENERIC_CLOCKEVENTS select MODULES_USE_ELF_RELA select HAVE_ARCH_TRACEHOOK + select HAVE_SYSCALL_TRACEPOINTS # FIXME: investigate whether we need/want these options. # select HAVE_IOREMAP_PROT diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h index e9c670d7a7fe..c96331eb5771 100644 --- a/arch/tile/include/asm/thread_info.h +++ b/arch/tile/include/asm/thread_info.h @@ -124,6 +124,7 @@ extern void _cpu_idle(void); #define TIF_SECCOMP 6 /* secure computing */ #define TIF_MEMDIE 7 /* OOM killer at work */ #define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ +#define TIF_SYSCALL_TRACEPOINT 9 /* syscall tracepoint instrumentation */ #define _TIF_SIGPENDING (1< #include +#define CREATE_TRACE_POINTS +#include + void user_enable_single_step(struct task_struct *child) { set_tsk_thread_flag(child, TIF_SINGLESTEP); @@ -249,16 +252,24 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, int do_syscall_trace_enter(struct pt_regs *regs) { - if (tracehook_report_syscall_entry(regs)) { - regs->regs[TREG_SYSCALL_NR] = -1; + if (test_thread_flag(TIF_SYSCALL_TRACE)) { + if (tracehook_report_syscall_entry(regs)) + regs->regs[TREG_SYSCALL_NR] = -1; } + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) + trace_sys_enter(regs, regs->regs[TREG_SYSCALL_NR]); + return regs->regs[TREG_SYSCALL_NR]; } void do_syscall_trace_exit(struct pt_regs *regs) { - tracehook_report_syscall_exit(regs, 0); + if (test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, 0); + + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) + trace_sys_exit(regs, regs->regs[TREG_SYSCALL_NR]); } void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) From adf6d9b30f089c52e674e84ca2960581e504e5e3 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Fri, 1 Feb 2013 12:37:48 -0500 Subject: [PATCH 06/11] tile: support atomic64_dec_if_positive() Use the normal cmpxchg() idiom to implement this functionality. Signed-off-by: Chris Metcalf --- arch/tile/Kconfig | 1 + arch/tile/include/asm/atomic.h | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 0e500d90c2a0..9a9d08637ab9 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -24,6 +24,7 @@ config TILE select MODULES_USE_ELF_RELA select HAVE_ARCH_TRACEHOOK select HAVE_SYSCALL_TRACEPOINTS + select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE # FIXME: investigate whether we need/want these options. # select HAVE_IOREMAP_PROT diff --git a/arch/tile/include/asm/atomic.h b/arch/tile/include/asm/atomic.h index f2461429a4a4..e71387ab20ca 100644 --- a/arch/tile/include/asm/atomic.h +++ b/arch/tile/include/asm/atomic.h @@ -131,4 +131,25 @@ static inline int atomic_read(const atomic_t *v) #include #endif +#ifndef __ASSEMBLY__ + +static inline long long atomic64_dec_if_positive(atomic64_t *v) +{ + long long c, old, dec; + + c = atomic64_read(v); + for (;;) { + dec = c - 1; + if (unlikely(dec < 0)) + break; + old = atomic64_cmpxchg((v), c, dec); + if (likely(old == c)) + break; + c = old; + } + return dec; +} + +#endif /* __ASSEMBLY__ */ + #endif /* _ASM_TILE_ATOMIC_H */ From 1dda7bbe113ad9f314c382e8309928e557361222 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Thu, 21 Mar 2013 20:12:19 +0100 Subject: [PATCH 07/11] tile: remove two outdated Kconfig entries Tile support got added in v2.6.36. Its main Kconfig file was added with two outdated Kconfig entries. DEFAULT_MIGRATION_COST is unused since v2.6.23, and SEMAPHORE_SLEEPERS is unused since v2.6.26. Remove these outdated entries now. Signed-off-by: Paul Bolle Signed-off-by: Chris Metcalf --- arch/tile/Kconfig | 9 --------- 1 file changed, 9 deletions(-) diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 9a9d08637ab9..d8885fd87603 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -43,9 +43,6 @@ config MMU config GENERIC_CSUM def_bool y -config SEMAPHORE_SLEEPERS - def_bool y - config HAVE_ARCH_ALLOC_REMAP def_bool y @@ -70,12 +67,6 @@ config HUGETLB_SUPER_PAGES config RWSEM_GENERIC_SPINLOCK def_bool y -# We have a very flat architecture from a migration point of view, -# so save boot time by presetting this (particularly useful on tile-sim). -config DEFAULT_MIGRATION_COST - int - default "10000000" - # We only support gcc 4.4 and above, so this should work. config ARCH_SUPPORTS_OPTIMIZED_INLINING def_bool y From d9acae6baf41c0561f8c532b20cfd955fd1edc2d Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Fri, 22 Mar 2013 01:40:51 +0100 Subject: [PATCH 08/11] arch: remove KCORE_ELF again [tile] The Kconfig symbol KCORE_ELF was removed in v2.6.0, but reappeared in two architectures. It is useless. Remove it again. Signed-off-by: Paul Bolle Signed-off-by: Chris Metcalf (tile only) --- arch/tile/Kconfig | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index d8885fd87603..7b82e68c5f55 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -414,11 +414,6 @@ endmenu menu "Executable file formats" -# only elf supported -config KCORE_ELF - def_bool y - depends on PROC_FS - source "fs/Kconfig.binfmt" endmenu From 39e8202bb3b83a826e5825b1a07bbbf30ae9a140 Mon Sep 17 00:00:00 2001 From: Henrik Austad Date: Tue, 26 Mar 2013 08:16:42 +0100 Subject: [PATCH 09/11] tile: ns2cycles should use __raw_get_cpu_var ns2cycles use per_cpu variables, and will, eventually, find its way into smp_processor_id(). This is not safe in a preemptible kernel; preemption should ideally be disabled. BUG: using smp_processor_id() in preemptible [00000000] code: systemd-modules/367 caller is ns2cycles+0x40/0xb8 Starting stack dump of tid 367, pid 367 (systemd-modules) on cpu 2 at cycle 20969956421 frame 0: 0xfffffff70004b860 dump_stack+0x0/0x20 (sp 0xfffffe407993fa90) frame 1: 0xfffffff7006abc28 debug_smp_processor_id+0x1a8/0x1e0 (sp 0xfffffe407993fa90) frame 2: 0xfffffff7004d7b40 ns2cycles+0x40/0xb8 (sp 0xfffffe407993fab8) frame 3: 0xfffffff7004dc578 __ndelay+0x38/0x80 (sp 0xfffffe407993fae0) However, in this case: - the frequency is the same accross all cores - we use the data read-only - we do not scale the frequency Which means that we can use the __raw_get_cpu_var instead. Signed-off-by: Henrik Austad Signed-off-by: Chris Metcalf --- arch/tile/kernel/time.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c index f6f50f2a5e37..5ac397ec6986 100644 --- a/arch/tile/kernel/time.c +++ b/arch/tile/kernel/time.c @@ -230,6 +230,10 @@ int setup_profiling_timer(unsigned int multiplier) */ cycles_t ns2cycles(unsigned long nsecs) { - struct clock_event_device *dev = &__get_cpu_var(tile_timer); + /* + * We do not have to disable preemption here as each core has the same + * clock frequency. + */ + struct clock_event_device *dev = &__raw_get_cpu_var(tile_timer); return ((u64)nsecs * dev->mult) >> dev->shift; } From ffae3d0e3606b2e274c9ec1b969342d630b2ecae Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Tue, 9 Apr 2013 12:33:07 -0400 Subject: [PATCH 10/11] tile: comment assumption about __insn_mtspr for The arch_local_irq_save(), etc., routines are required to function as compiler barriers. They do, but it's subtle and requires knowing that the gcc builtin __insn_mtspr() is marked as a memory clobber. Provide a comment explaining the assumption. Signed-off-by: Chris Metcalf --- arch/tile/include/asm/irqflags.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/tile/include/asm/irqflags.h b/arch/tile/include/asm/irqflags.h index 241c0bb60b12..c96f9bbb760d 100644 --- a/arch/tile/include/asm/irqflags.h +++ b/arch/tile/include/asm/irqflags.h @@ -40,7 +40,15 @@ #include #include -/* Set and clear kernel interrupt masks. */ +/* + * Set and clear kernel interrupt masks. + * + * NOTE: __insn_mtspr() is a compiler builtin marked as a memory + * clobber. We rely on it being equivalent to a compiler barrier in + * this code since arch_local_irq_save() and friends must act as + * compiler barriers. This compiler semantic is baked into enough + * places that the compiler will maintain it going forward. + */ #if CHIP_HAS_SPLIT_INTR_MASK() #if INT_PERF_COUNT < 32 || INT_AUX_PERF_COUNT < 32 || INT_MEM_ERROR >= 32 # error Fix assumptions about which word various interrupts are in From 9fc1894c9883439245b225d16100d6a55b25373a Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Wed, 17 Apr 2013 11:01:22 -0400 Subject: [PATCH 11/11] arch/tile: Fix syscall return value passed to tracepoint Currently the syscall number is passed, but it should be the return value, which is kept in r0. Signed-off-by: Simon Marchi Signed-off-by: Chris Metcalf [using a raw 0 value] --- arch/tile/kernel/ptrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c index 363b2dd20f99..0f83ed4602b2 100644 --- a/arch/tile/kernel/ptrace.c +++ b/arch/tile/kernel/ptrace.c @@ -269,7 +269,7 @@ void do_syscall_trace_exit(struct pt_regs *regs) tracehook_report_syscall_exit(regs, 0); if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) - trace_sys_exit(regs, regs->regs[TREG_SYSCALL_NR]); + trace_sys_exit(regs, regs->regs[0]); } void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)