summaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/kernel/entry-armv.S10
-rw-r--r--arch/arm/kernel/traps.c11
-rw-r--r--arch/arm/mm/Kconfig24
3 files changed, 25 insertions, 20 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 080df907f24..c6af1a03e08 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -505,9 +505,9 @@ ENTRY(__switch_to)
mra r4, r5, acc0
stmia ip, {r4, r5}
#endif
-#ifdef CONFIG_HAS_TLS_REG
+#if defined(CONFIG_HAS_TLS_REG)
mcr p15, 0, r3, c13, c0, 3 @ set TLS register
-#else
+#elif !defined(CONFIG_TLS_REG_EMUL)
mov r4, #0xffff0fff
str r3, [r4, #-15] @ TLS val at 0xffff0ff0
#endif
@@ -690,11 +690,7 @@ __kuser_cmpxchg: @ 0xffff0fc0
__kuser_get_tls: @ 0xffff0fe0
-#ifndef CONFIG_HAS_TLS_REG
-
-#ifdef CONFIG_SMP /* sanity check */
-#error "CONFIG_SMP without CONFIG_HAS_TLS_REG is wrong"
-#endif
+#if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL)
ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0
mov pc, lr
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 8988c02119f..14df16b983f 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -451,9 +451,9 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
case NR(set_tls):
thread->tp_value = regs->ARM_r0;
-#ifdef CONFIG_HAS_TLS_REG
+#if defined(CONFIG_HAS_TLS_REG)
asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) );
-#else
+#elif !defined(CONFIG_TLS_REG_EMUL)
/*
* User space must never try to access this directly.
* Expect your app to break eventually if you do so.
@@ -498,11 +498,14 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
return 0;
}
-#if defined(CONFIG_CPU_32v6) && !defined(CONFIG_HAS_TLS_REG)
+#ifdef CONFIG_TLS_REG_EMUL
/*
* We might be running on an ARMv6+ processor which should have the TLS
- * register, but for some reason we can't use it and have to emulate it.
+ * register but for some reason we can't use it, or maybe an SMP system
+ * using a pre-ARMv6 processor (there are apparently a few prototypes like
+ * that in existence) and therefore access to that register must be
+ * emulated.
*/
static int get_tp_trap(struct pt_regs *regs, unsigned int instr)
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 27892e34b06..c4fc6be629d 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -410,17 +410,23 @@ config CPU_BPREDICT_DISABLE
help
Say Y here to disable branch prediction. If unsure, say N.
+config TLS_REG_EMUL
+ bool
+ default y if (SMP || CPU_32v6) && (CPU_32v5 || CPU_32v4 || CPU_32v3)
+ help
+ We might be running on an ARMv6+ processor which should have the TLS
+ register but for some reason we can't use it, or maybe an SMP system
+ using a pre-ARMv6 processor (there are apparently a few prototypes
+ like that in existence) and therefore access to that register must
+ be emulated.
+
config HAS_TLS_REG
bool
- depends on CPU_32v6 && !CPU_32v5 && !CPU_32v4 && !CPU_32v3
- default y
+ depends on CPU_32v6
+ default y if !TLS_REG_EMUL
help
This selects support for the CP15 thread register.
- It is defined to be available on ARMv6 or later. However
- if the kernel is configured to support multiple CPUs including
- a pre-ARMv6 processors, or if a given ARMv6 processor doesn't
- implement the thread register for some reason, then access to
- this register from user space must be trapped and emulated.
- If user space is relying on the __kuser_get_tls code then
- there should not be any impact.
+ It is defined to be available on ARMv6 or later. If a particular
+ ARMv6 or later CPU doesn't support it then it must omc;ide "select
+ TLS_REG_EMUL" along with its other caracteristics.