aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/kernel/process.c18
-rw-r--r--arch/arm64/kernel/sys_compat.c6
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
233static 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
233void flush_thread(void) 250void 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