Explorar o código

[ARM] Fix VFP initialisation issue for SMP systems

When we install the handlers for context switching, we must enable
VFP on all CPU cores, otherwise undefined (and random) effects
occur.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Russell King %!s(int64=18) %!d(string=hai) anos
pai
achega
8e140362f7
Modificáronse 1 ficheiros con 15 adicións e 0 borrados
  1. 15 0
      arch/arm/vfp/vfpmodule.c

+ 15 - 0
arch/arm/vfp/vfpmodule.c

@@ -264,6 +264,18 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
 		vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
 }
 
+static void vfp_enable(void *unused)
+{
+	u32 access = get_copro_access();
+
+	/*
+	 * Enable full access to VFP (cp10 and cp11)
+	 */
+	set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
+}
+
+#include <linux/smp.h>
+
 /*
  * VFP support code initialisation.
  */
@@ -288,6 +300,7 @@ static int __init vfp_init(void)
 	 * we just need to read the VFPSID register.
 	 */
 	vfpsid = fmrx(FPSID);
+	barrier();
 
 	printk(KERN_INFO "VFP support v0.3: ");
 	if (VFP_arch) {
@@ -301,6 +314,8 @@ static int __init vfp_init(void)
 	} else if (vfpsid & FPSID_NODOUBLE) {
 		printk("no double precision support\n");
 	} else {
+		smp_call_function(vfp_enable, NULL, 1, 1);
+
 		VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT;  /* Extract the architecture version */
 		printk("implementor %02x architecture %d part %02x variant %x rev %x\n",
 			(vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,