Skip to content

Commit c275591

Browse files
committed
ARM: smp: defer TPIDRURO update for SMP v6 configurations too
Defer TPIDURO updates for user space until exit also for CPU_V6+SMP configurations so that we can decide at runtime whether to use it to carry the current pointer, provided that we are running on a CPU that actually implements this register. This is needed for THREAD_INFO_IN_TASK support for UP systems, which requires that all SMP capable systems use the TPIDRURO based access to 'current' as the only remaining alternative will be a global variable which only works on UP. Acked-by: Linus Walleij <[email protected]> Acked-by: Nicolas Pitre <[email protected]> Signed-off-by: Ard Biesheuvel <[email protected]> Tested-by: Marc Zyngier <[email protected]> Tested-by: Vladimir Murzin <[email protected]> # ARMv7M
1 parent b87cf91 commit c275591

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

arch/arm/include/asm/tls.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@
1818
.endm
1919

2020
.macro switch_tls_v6, base, tp, tpuser, tmp1, tmp2
21-
ldr \tmp1, =elf_hwcap
22-
ldr \tmp1, [\tmp1, #0]
21+
ldr_va \tmp1, elf_hwcap
2322
mov \tmp2, #0xffff0fff
2423
tst \tmp1, #HWCAP_TLS @ hardware TLS available?
2524
streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0
2625
mrcne p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register
26+
#ifndef CONFIG_SMP
2727
mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register
28+
#endif
2829
mcrne p15, 0, \tpuser, c13, c0, 2 @ set user r/w register
2930
strne \tmp2, [\base, #TI_TP_VALUE + 4] @ save it
3031
.endm
@@ -43,7 +44,7 @@
4344
#elif defined(CONFIG_CPU_V6)
4445
#define tls_emu 0
4546
#define has_tls_reg (elf_hwcap & HWCAP_TLS)
46-
#define defer_tls_reg_update 0
47+
#define defer_tls_reg_update IS_ENABLED(CONFIG_SMP)
4748
#define switch_tls switch_tls_v6
4849
#elif defined(CONFIG_CPU_32v6K)
4950
#define tls_emu 0
@@ -81,11 +82,11 @@ static inline void set_tls(unsigned long val)
8182
*/
8283
barrier();
8384

84-
if (!tls_emu && !defer_tls_reg_update) {
85-
if (has_tls_reg) {
85+
if (!tls_emu) {
86+
if (has_tls_reg && !defer_tls_reg_update) {
8687
asm("mcr p15, 0, %0, c13, c0, 3"
8788
: : "r" (val));
88-
} else {
89+
} else if (!has_tls_reg) {
8990
#ifdef CONFIG_KUSER_HELPERS
9091
/*
9192
* User space must never try to access this

arch/arm/kernel/entry-header.S

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,12 +292,21 @@
292292

293293

294294
.macro restore_user_regs, fast = 0, offset = 0
295-
#if defined(CONFIG_CPU_32v6K) && !defined(CONFIG_CPU_V6)
295+
#if defined(CONFIG_CPU_32v6K) || defined(CONFIG_SMP)
296+
#if defined(CONFIG_CPU_V6) && defined(CONFIG_SMP)
297+
ALT_SMP(b .L1_\@ )
298+
ALT_UP( nop )
299+
ldr_va r1, elf_hwcap
300+
tst r1, #HWCAP_TLS @ hardware TLS available?
301+
beq .L2_\@
302+
.L1_\@:
303+
#endif
296304
@ The TLS register update is deferred until return to user space so we
297305
@ can use it for other things while running in the kernel
298306
get_thread_info r1
299307
ldr r1, [r1, #TI_TP_VALUE]
300308
mcr p15, 0, r1, c13, c0, 3 @ set TLS register
309+
.L2_\@:
301310
#endif
302311

303312
uaccess_enable r1, isb=0

0 commit comments

Comments
 (0)