aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>2018-06-02 08:43:56 -0400
committerThomas Gleixner <tglx@linutronix.de>2018-06-06 05:58:31 -0400
commitb74406f37737c91c5ede7c625d9d31482a8a4290 (patch)
tree3954938fe9b662fd50ea4e847b4e6bf1d63528df
parent9800b9dc13cdffb7f627e4818ba7768ff62febac (diff)
arm: Add syscall detection for restartable sequences
Syscalls are not allowed inside restartable sequences, so add a call to rseq_syscall() at the very beginning of system call exiting path for CONFIG_DEBUG_RSEQ=y kernel. This could help us to detect whether there is a syscall issued inside restartable sequences. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Joel Fernandes <joelaf@google.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Dave Watson <davejwatson@fb.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: "H . Peter Anvin" <hpa@zytor.com> Cc: Chris Lameter <cl@linux.com> Cc: Russell King <linux@arm.linux.org.uk> Cc: Andrew Hunter <ahh@google.com> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Cc: "Paul E . McKenney" <paulmck@linux.vnet.ibm.com> Cc: Paul Turner <pjt@google.com> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Josh Triplett <josh@joshtriplett.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Ben Maurer <bmaurer@fb.com> Cc: linux-api@vger.kernel.org Cc: Andy Lutomirski <luto@amacapital.net> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Link: https://lkml.kernel.org/r/20180602124408.8430-5-mathieu.desnoyers@efficios.com
-rw-r--r--arch/arm/kernel/entry-common.S25
-rw-r--r--arch/arm/kernel/signal.c7
2 files changed, 26 insertions, 6 deletions
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 3c4f88701f22..b427ef8ec8c6 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -39,12 +39,13 @@ saved_pc .req lr
39 39
40 .section .entry.text,"ax",%progbits 40 .section .entry.text,"ax",%progbits
41 .align 5 41 .align 5
42#if !(IS_ENABLED(CONFIG_TRACE_IRQFLAGS) || IS_ENABLED(CONFIG_CONTEXT_TRACKING)) 42#if !(IS_ENABLED(CONFIG_TRACE_IRQFLAGS) || IS_ENABLED(CONFIG_CONTEXT_TRACKING) || \
43 IS_ENABLED(CONFIG_DEBUG_RSEQ))
43/* 44/*
44 * This is the fast syscall return path. We do as little as possible here, 45 * This is the fast syscall return path. We do as little as possible here,
45 * such as avoiding writing r0 to the stack. We only use this path if we 46 * such as avoiding writing r0 to the stack. We only use this path if we
46 * have tracing and context tracking disabled - the overheads from those 47 * have tracing, context tracking and rseq debug disabled - the overheads
47 * features make this path too inefficient. 48 * from those features make this path too inefficient.
48 */ 49 */
49ret_fast_syscall: 50ret_fast_syscall:
50 UNWIND(.fnstart ) 51 UNWIND(.fnstart )
@@ -71,14 +72,20 @@ fast_work_pending:
71 /* fall through to work_pending */ 72 /* fall through to work_pending */
72#else 73#else
73/* 74/*
74 * The "replacement" ret_fast_syscall for when tracing or context tracking 75 * The "replacement" ret_fast_syscall for when tracing, context tracking,
75 * is enabled. As we will need to call out to some C functions, we save 76 * or rseq debug is enabled. As we will need to call out to some C functions,
76 * r0 first to avoid needing to save registers around each C function call. 77 * we save r0 first to avoid needing to save registers around each C function
78 * call.
77 */ 79 */
78ret_fast_syscall: 80ret_fast_syscall:
79 UNWIND(.fnstart ) 81 UNWIND(.fnstart )
80 UNWIND(.cantunwind ) 82 UNWIND(.cantunwind )
81 str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 83 str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
84#if IS_ENABLED(CONFIG_DEBUG_RSEQ)
85 /* do_rseq_syscall needs interrupts enabled. */
86 mov r0, sp @ 'regs'
87 bl do_rseq_syscall
88#endif
82 disable_irq_notrace @ disable interrupts 89 disable_irq_notrace @ disable interrupts
83 ldr r2, [tsk, #TI_ADDR_LIMIT] 90 ldr r2, [tsk, #TI_ADDR_LIMIT]
84 cmp r2, #TASK_SIZE 91 cmp r2, #TASK_SIZE
@@ -113,6 +120,12 @@ ENDPROC(ret_fast_syscall)
113 */ 120 */
114ENTRY(ret_to_user) 121ENTRY(ret_to_user)
115ret_slow_syscall: 122ret_slow_syscall:
123#if IS_ENABLED(CONFIG_DEBUG_RSEQ)
124 /* do_rseq_syscall needs interrupts enabled. */
125 enable_irq_notrace @ enable interrupts
126 mov r0, sp @ 'regs'
127 bl do_rseq_syscall
128#endif
116 disable_irq_notrace @ disable interrupts 129 disable_irq_notrace @ disable interrupts
117ENTRY(ret_to_user_from_irq) 130ENTRY(ret_to_user_from_irq)
118 ldr r2, [tsk, #TI_ADDR_LIMIT] 131 ldr r2, [tsk, #TI_ADDR_LIMIT]
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 5879ab3f53c1..f09e9d66d605 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -710,3 +710,10 @@ asmlinkage void addr_limit_check_failed(void)
710{ 710{
711 addr_limit_user_check(); 711 addr_limit_user_check();
712} 712}
713
714#ifdef CONFIG_DEBUG_RSEQ
715asmlinkage void do_rseq_syscall(struct pt_regs *regs)
716{
717 rseq_syscall(regs);
718}
719#endif