aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/entry.S
diff options
context:
space:
mode:
authorJames Morse <james.morse@arm.com>2016-06-20 13:28:01 -0400
committerWill Deacon <will.deacon@arm.com>2016-07-07 10:55:37 -0400
commite19a6ee2460bdd0d0055a6029383422773f9999a (patch)
treef8e7898101568c82617d7afd66e712b9f0538a0e /arch/arm64/kernel/entry.S
parent4c2e07c6a29e0129e975727b9f57eede813eea85 (diff)
arm64: kernel: Save and restore UAO and addr_limit on exception entry
If we take an exception while at EL1, the exception handler inherits the original context's addr_limit and PSTATE.UAO values. To be consistent always reset addr_limit and PSTATE.UAO on (re-)entry to EL1. This prevents accidental re-use of the original context's addr_limit. Based on a similar patch for arm from Russell King. Cc: <stable@vger.kernel.org> # 4.6- Acked-by: Will Deacon <will.deacon@arm.com> Reviewed-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64/kernel/entry.S')
-rw-r--r--arch/arm64/kernel/entry.S19
1 files changed, 17 insertions, 2 deletions
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 12e8d2bcb3f9..6c3b7345a6c4 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -28,6 +28,7 @@
28#include <asm/errno.h> 28#include <asm/errno.h>
29#include <asm/esr.h> 29#include <asm/esr.h>
30#include <asm/irq.h> 30#include <asm/irq.h>
31#include <asm/memory.h>
31#include <asm/thread_info.h> 32#include <asm/thread_info.h>
32#include <asm/unistd.h> 33#include <asm/unistd.h>
33 34
@@ -97,7 +98,14 @@
97 mov x29, xzr // fp pointed to user-space 98 mov x29, xzr // fp pointed to user-space
98 .else 99 .else
99 add x21, sp, #S_FRAME_SIZE 100 add x21, sp, #S_FRAME_SIZE
100 .endif 101 get_thread_info tsk
102 /* Save the task's original addr_limit and set USER_DS (TASK_SIZE_64) */
103 ldr x20, [tsk, #TI_ADDR_LIMIT]
104 str x20, [sp, #S_ORIG_ADDR_LIMIT]
105 mov x20, #TASK_SIZE_64
106 str x20, [tsk, #TI_ADDR_LIMIT]
107 ALTERNATIVE(nop, SET_PSTATE_UAO(0), ARM64_HAS_UAO, CONFIG_ARM64_UAO)
108 .endif /* \el == 0 */
101 mrs x22, elr_el1 109 mrs x22, elr_el1
102 mrs x23, spsr_el1 110 mrs x23, spsr_el1
103 stp lr, x21, [sp, #S_LR] 111 stp lr, x21, [sp, #S_LR]
@@ -128,6 +136,14 @@
128 .endm 136 .endm
129 137
130 .macro kernel_exit, el 138 .macro kernel_exit, el
139 .if \el != 0
140 /* Restore the task's original addr_limit. */
141 ldr x20, [sp, #S_ORIG_ADDR_LIMIT]
142 str x20, [tsk, #TI_ADDR_LIMIT]
143
144 /* No need to restore UAO, it will be restored from SPSR_EL1 */
145 .endif
146
131 ldp x21, x22, [sp, #S_PC] // load ELR, SPSR 147 ldp x21, x22, [sp, #S_PC] // load ELR, SPSR
132 .if \el == 0 148 .if \el == 0
133 ct_user_enter 149 ct_user_enter
@@ -406,7 +422,6 @@ el1_irq:
406 bl trace_hardirqs_off 422 bl trace_hardirqs_off
407#endif 423#endif
408 424
409 get_thread_info tsk
410 irq_handler 425 irq_handler
411 426
412#ifdef CONFIG_PREEMPT 427#ifdef CONFIG_PREEMPT