diff options
author | Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | 2018-06-02 08:43:56 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2018-06-06 05:58:31 -0400 |
commit | b74406f37737c91c5ede7c625d9d31482a8a4290 (patch) | |
tree | 3954938fe9b662fd50ea4e847b4e6bf1d63528df | |
parent | 9800b9dc13cdffb7f627e4818ba7768ff62febac (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.S | 25 | ||||
-rw-r--r-- | arch/arm/kernel/signal.c | 7 |
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 | */ |
49 | ret_fast_syscall: | 50 | ret_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 | */ |
78 | ret_fast_syscall: | 80 | ret_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 | */ |
114 | ENTRY(ret_to_user) | 121 | ENTRY(ret_to_user) |
115 | ret_slow_syscall: | 122 | ret_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 |
117 | ENTRY(ret_to_user_from_irq) | 130 | ENTRY(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 | ||
715 | asmlinkage void do_rseq_syscall(struct pt_regs *regs) | ||
716 | { | ||
717 | rseq_syscall(regs); | ||
718 | } | ||
719 | #endif | ||