Commit 3855ab61 authored by Ard Biesheuvel's avatar Ard Biesheuvel
Browse files

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: default avatarArd Biesheuvel <ardb@kernel.org>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Tested-by: default avatarAmit Daniel Kachhap <amit.kachhap@arm.com>
parent 19f29aeb
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -12,8 +12,8 @@

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

@@ -38,18 +38,22 @@
#ifdef CONFIG_TLS_REG_EMUL
#define tls_emu		1
#define has_tls_reg		1
#define defer_tls_reg_update	0
#define switch_tls	switch_tls_none
#elif defined(CONFIG_CPU_V6)
#define tls_emu		0
#define has_tls_reg		(elf_hwcap & HWCAP_TLS)
#define defer_tls_reg_update	0
#define switch_tls	switch_tls_v6
#elif defined(CONFIG_CPU_32v6K)
#define tls_emu		0
#define has_tls_reg		1
#define defer_tls_reg_update	1
#define switch_tls	switch_tls_v6k
#else
#define tls_emu		0
#define has_tls_reg		0
#define defer_tls_reg_update	0
#define switch_tls	switch_tls_software
#endif

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

	if (!tls_emu) {
	if (!tls_emu && !defer_tls_reg_update) {
		if (has_tls_reg) {
			asm("mcr p15, 0, %0, c13, c0, 3"
			    : : "r" (val));
+8 −0
Original line number Diff line number Diff line
@@ -292,6 +292,14 @@


	.macro	restore_user_regs, fast = 0, offset = 0
#if defined(CONFIG_CPU_32v6K) && !defined(CONFIG_CPU_V6)
	@ The TLS register update is deferred until return to user space so we
	@ can use it for other things while running in the kernel
	get_thread_info r1
	ldr	r1, [r1, #TI_TP_VALUE]
	mcr	p15, 0, r1, c13, c0, 3		@ set TLS register
#endif

	uaccess_enable r1, isb=0
#ifndef CONFIG_THUMB2_KERNEL
	@ ARM mode restore