Skip to content

Commit 3855ab6

Browse files
committed
ARM: smp: Free up the TLS register while running in the kernel
To prepare for a subsequent patch that stores the current task pointer in the user space TLS register while running in the kernel, modify the set_tls and switch_tls routines not to touch the register directly, and update the return to user space code to load the correct value. Signed-off-by: Ard Biesheuvel <[email protected]> Reviewed-by: Linus Walleij <[email protected]> Tested-by: Amit Daniel Kachhap <[email protected]>
1 parent 19f29ae commit 3855ab6

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

arch/arm/include/asm/tls.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212

1313
.macro switch_tls_v6k, base, tp, tpuser, tmp1, tmp2
1414
mrc p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register
15-
mcr p15, 0, \tp, c13, c0, 3 @ set TLS register
16-
mcr p15, 0, \tpuser, c13, c0, 2 @ and the user r/w register
15+
@ TLS register update is deferred until return to user space
16+
mcr p15, 0, \tpuser, c13, c0, 2 @ set the user r/w register
1717
str \tmp2, [\base, #TI_TP_VALUE + 4] @ save it
1818
.endm
1919

@@ -38,18 +38,22 @@
3838
#ifdef CONFIG_TLS_REG_EMUL
3939
#define tls_emu 1
4040
#define has_tls_reg 1
41+
#define defer_tls_reg_update 0
4142
#define switch_tls switch_tls_none
4243
#elif defined(CONFIG_CPU_V6)
4344
#define tls_emu 0
4445
#define has_tls_reg (elf_hwcap & HWCAP_TLS)
46+
#define defer_tls_reg_update 0
4547
#define switch_tls switch_tls_v6
4648
#elif defined(CONFIG_CPU_32v6K)
4749
#define tls_emu 0
4850
#define has_tls_reg 1
51+
#define defer_tls_reg_update 1
4952
#define switch_tls switch_tls_v6k
5053
#else
5154
#define tls_emu 0
5255
#define has_tls_reg 0
56+
#define defer_tls_reg_update 0
5357
#define switch_tls switch_tls_software
5458
#endif
5559

@@ -77,7 +81,7 @@ static inline void set_tls(unsigned long val)
7781
*/
7882
barrier();
7983

80-
if (!tls_emu) {
84+
if (!tls_emu && !defer_tls_reg_update) {
8185
if (has_tls_reg) {
8286
asm("mcr p15, 0, %0, c13, c0, 3"
8387
: : "r" (val));

arch/arm/kernel/entry-header.S

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,14 @@
292292

293293

294294
.macro restore_user_regs, fast = 0, offset = 0
295+
#if defined(CONFIG_CPU_32v6K) && !defined(CONFIG_CPU_V6)
296+
@ The TLS register update is deferred until return to user space so we
297+
@ can use it for other things while running in the kernel
298+
get_thread_info r1
299+
ldr r1, [r1, #TI_TP_VALUE]
300+
mcr p15, 0, r1, c13, c0, 3 @ set TLS register
301+
#endif
302+
295303
uaccess_enable r1, isb=0
296304
#ifndef CONFIG_THUMB2_KERNEL
297305
@ ARM mode restore

0 commit comments

Comments
 (0)