path: root/arch/arm/kernel/entry-armv.S
diff options
authorAndré Hentschel <nerv@dawncrow.de>2013-06-18 23:23:26 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-06-24 15:21:59 +0100
commita4780adeefd042482f624f5e0d577bf9cdcbb760 (patch)
treeead0e79b4f797a26cc30fc1596ada6fd6da5daf6 /arch/arm/kernel/entry-armv.S
parent4a1b573346ee0d64d95beb78d49a5bbb574e6c6a (diff)
ARM: 7735/2: Preserve the user r/w register TPIDRURW on context switch and fork
Since commit 6a1c53124aa1 the user writeable TLS register was zeroed to prevent it from being used as a covert channel between two tasks. There are more and more applications coming to Windows RT, Wine could support them, but mostly they expect to have the thread environment block (TEB) in TPIDRURW. This patch preserves that register per thread instead of clearing it. Unlike the TPIDRURO, which is already switched, the TPIDRURW can be updated from userspace so needs careful treatment in the case that we modify TPIDRURW and call fork(). To avoid this we must always read TPIDRURW in copy_thread. Signed-off-by: André Hentschel <nerv@dawncrow.de> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Jonathan Austin <jonathan.austin@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/entry-armv.S')
1 files changed, 3 insertions, 2 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 582b405befc5..a39cfc2a1f90 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -685,15 +685,16 @@ ENTRY(__switch_to)
UNWIND(.fnstart )
UNWIND(.cantunwind )
add ip, r1, #TI_CPU_SAVE
- ldr r3, [r2, #TI_TP_VALUE]
ARM( stmia ip!, {r4 - sl, fp, sp, lr} ) @ Store most regs on stack
THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack
THUMB( str sp, [ip], #4 )
THUMB( str lr, [ip], #4 )
+ ldr r4, [r2, #TI_TP_VALUE]
+ ldr r5, [r2, #TI_TP_VALUE + 4]
ldr r6, [r2, #TI_CPU_DOMAIN]
- set_tls r3, r4, r5
+ switch_tls r1, r4, r5, r3, r7
ldr r7, [r2, #TI_TASK]
ldr r8, =__stack_chk_guard