浏览代码

[PATCH] ARM: 2663/1: straightify TLS register emulation a bit more

Patch from Nicolas Pitre

This better express things, and should cover RMK's weird SMP toys.

Signed-off-by: Nicolas Pitre
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Nicolas Pitre 20 年之前
父节点
当前提交
4b0e07a556
共有 3 个文件被更改,包括 25 次插入20 次删除
  1. 3 7
      arch/arm/kernel/entry-armv.S
  2. 7 4
      arch/arm/kernel/traps.c
  3. 15 9
      arch/arm/mm/Kconfig

+ 3 - 7
arch/arm/kernel/entry-armv.S

@@ -505,9 +505,9 @@ ENTRY(__switch_to)
 	mra	r4, r5, acc0
 	mra	r4, r5, acc0
 	stmia   ip, {r4, r5}
 	stmia   ip, {r4, r5}
 #endif
 #endif
-#ifdef CONFIG_HAS_TLS_REG
+#if defined(CONFIG_HAS_TLS_REG)
 	mcr	p15, 0, r3, c13, c0, 3		@ set TLS register
 	mcr	p15, 0, r3, c13, c0, 3		@ set TLS register
-#else
+#elif !defined(CONFIG_TLS_REG_EMUL)
 	mov	r4, #0xffff0fff
 	mov	r4, #0xffff0fff
 	str	r3, [r4, #-15]			@ TLS val at 0xffff0ff0
 	str	r3, [r4, #-15]			@ TLS val at 0xffff0ff0
 #endif
 #endif
@@ -690,11 +690,7 @@ __kuser_cmpxchg:				@ 0xffff0fc0
 
 
 __kuser_get_tls:				@ 0xffff0fe0
 __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
 	ldr	r0, [pc, #(16 - 8)]		@ TLS stored at 0xffff0ff0
 	mov	pc, lr
 	mov	pc, lr

+ 7 - 4
arch/arm/kernel/traps.c

@@ -451,9 +451,9 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
 
 
 	case NR(set_tls):
 	case NR(set_tls):
 		thread->tp_value = regs->ARM_r0;
 		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) );
 		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.
 		 * User space must never try to access this directly.
 		 * Expect your app to break eventually if you do so.
 		 * 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;
 	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
  * 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)
 static int get_tp_trap(struct pt_regs *regs, unsigned int instr)

+ 15 - 9
arch/arm/mm/Kconfig

@@ -410,17 +410,23 @@ config CPU_BPREDICT_DISABLE
 	help
 	help
 	  Say Y here to disable branch prediction.  If unsure, say N.
 	  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
 config HAS_TLS_REG
 	bool
 	bool
-	depends on CPU_32v6 && !CPU_32v5 && !CPU_32v4 && !CPU_32v3
-	default y
+	depends on CPU_32v6
+	default y if !TLS_REG_EMUL
 	help
 	help
 	  This selects support for the CP15 thread register.
 	  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.