mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
commit 6a1c53124a upstream.
TPIDRURW is a user read/write register forming part of the group of
thread registers in more recent versions of the ARM architecture (~v6+).
Currently, the kernel does not touch this register, which allows tasks
to communicate covertly by reading and writing to the register without
context-switching affecting its contents.
This patch clears TPIDRURW when TPIDRURO is updated via the set_tls
macro, which is called directly from __switch_to. Since the current
behaviour makes the register useless to userspace as far as thread
pointers are concerned, simply clearing the register (rather than saving
and restoring it) will not cause any problems to userspace.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
50 lines
1.2 KiB
C
50 lines
1.2 KiB
C
#ifndef __ASMARM_TLS_H
|
|
#define __ASMARM_TLS_H
|
|
|
|
#ifdef __ASSEMBLY__
|
|
.macro set_tls_none, tp, tmp1, tmp2
|
|
.endm
|
|
|
|
.macro set_tls_v6k, tp, tmp1, tmp2
|
|
mcr p15, 0, \tp, c13, c0, 3 @ set TLS register
|
|
mov \tmp1, #0
|
|
mcr p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register
|
|
.endm
|
|
|
|
.macro set_tls_v6, tp, tmp1, tmp2
|
|
ldr \tmp1, =elf_hwcap
|
|
ldr \tmp1, [\tmp1, #0]
|
|
mov \tmp2, #0xffff0fff
|
|
tst \tmp1, #HWCAP_TLS @ hardware TLS available?
|
|
mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register
|
|
movne \tmp1, #0
|
|
mcrne p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register
|
|
streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0
|
|
.endm
|
|
|
|
.macro set_tls_software, tp, tmp1, tmp2
|
|
mov \tmp1, #0xffff0fff
|
|
str \tp, [\tmp1, #-15] @ set TLS value at 0xffff0ff0
|
|
.endm
|
|
#endif
|
|
|
|
#ifdef CONFIG_TLS_REG_EMUL
|
|
#define tls_emu 1
|
|
#define has_tls_reg 1
|
|
#define set_tls set_tls_none
|
|
#elif defined(CONFIG_CPU_V6)
|
|
#define tls_emu 0
|
|
#define has_tls_reg (elf_hwcap & HWCAP_TLS)
|
|
#define set_tls set_tls_v6
|
|
#elif defined(CONFIG_CPU_32v6K)
|
|
#define tls_emu 0
|
|
#define has_tls_reg 1
|
|
#define set_tls set_tls_v6k
|
|
#else
|
|
#define tls_emu 0
|
|
#define has_tls_reg 0
|
|
#define set_tls set_tls_software
|
|
#endif
|
|
|
|
#endif /* __ASMARM_TLS_H */
|