diff options
-rw-r--r-- | arch/arm64/kernel/process.c | 18 | ||||
-rw-r--r-- | arch/arm64/kernel/sys_compat.c | 6 |
2 files changed, 24 insertions, 0 deletions
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 1309d64aa926..29d48690f2ac 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c | |||
@@ -230,9 +230,27 @@ void exit_thread(void) | |||
230 | { | 230 | { |
231 | } | 231 | } |
232 | 232 | ||
233 | static void tls_thread_flush(void) | ||
234 | { | ||
235 | asm ("msr tpidr_el0, xzr"); | ||
236 | |||
237 | if (is_compat_task()) { | ||
238 | current->thread.tp_value = 0; | ||
239 | |||
240 | /* | ||
241 | * We need to ensure ordering between the shadow state and the | ||
242 | * hardware state, so that we don't corrupt the hardware state | ||
243 | * with a stale shadow state during context switch. | ||
244 | */ | ||
245 | barrier(); | ||
246 | asm ("msr tpidrro_el0, xzr"); | ||
247 | } | ||
248 | } | ||
249 | |||
233 | void flush_thread(void) | 250 | void flush_thread(void) |
234 | { | 251 | { |
235 | fpsimd_flush_thread(); | 252 | fpsimd_flush_thread(); |
253 | tls_thread_flush(); | ||
236 | flush_ptrace_hw_breakpoint(current); | 254 | flush_ptrace_hw_breakpoint(current); |
237 | } | 255 | } |
238 | 256 | ||
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c index de2b0226e06d..dc47e53e9e28 100644 --- a/arch/arm64/kernel/sys_compat.c +++ b/arch/arm64/kernel/sys_compat.c | |||
@@ -79,6 +79,12 @@ long compat_arm_syscall(struct pt_regs *regs) | |||
79 | 79 | ||
80 | case __ARM_NR_compat_set_tls: | 80 | case __ARM_NR_compat_set_tls: |
81 | current->thread.tp_value = regs->regs[0]; | 81 | current->thread.tp_value = regs->regs[0]; |
82 | |||
83 | /* | ||
84 | * Protect against register corruption from context switch. | ||
85 | * See comment in tls_thread_flush. | ||
86 | */ | ||
87 | barrier(); | ||
82 | asm ("msr tpidrro_el0, %0" : : "r" (regs->regs[0])); | 88 | asm ("msr tpidrro_el0, %0" : : "r" (regs->regs[0])); |
83 | return 0; | 89 | return 0; |
84 | 90 | ||