diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 10 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 11 | ||||
-rw-r--r-- | arch/arm/mm/Kconfig | 24 |
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. |