]> xenbits.xensource.com Git - xen.git/commitdiff
xen/arm: Introduce enable callback to enable a capabilities on each online CPU
authorJulien Grall <julien.grall@linaro.org>
Tue, 16 Jan 2018 14:23:33 +0000 (14:23 +0000)
committerStefano Stabellini <sstabellini@kernel.org>
Wed, 24 Jan 2018 22:09:07 +0000 (14:09 -0800)
Once Xen knows what features/workarounds present on the platform, it
might be necessary to configure each online CPU.

Introduce a new callback "enable" that will be called on each online CPU to
configure the "capability".

The code is based on Linux v4.14 (where cpufeature.c comes from), the
explanation of why using stop_machine_run is kept as we have similar
problem in the future.

Lastly introduce enable_errata_workaround that will be called once CPUs
have booted and before the hardware domain is created.

This is part of XSA-254.

Signed-of-by: Julien Grall <julien.grall@linaro.org>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
(cherry picked from commit 7500495155aacce437878cb576f45224ae984f40)

Conflicts:
xen/include/asm-arm/cpufeature.h
xen/arch/arm/setup.c

xen/arch/arm/cpuerrata.c
xen/arch/arm/cpufeature.c
xen/arch/arm/setup.c
xen/include/asm-arm/cpuerrata.h
xen/include/asm-arm/cpufeature.h

index 03ae7b496c70f1946b120f8273cc0045df171d32..563cc7a0e4a41ac20e7fb0b450a445368e1a6581 100644 (file)
@@ -24,6 +24,12 @@ void check_local_cpu_errata(void)
 {
     update_cpu_capabilities(arm_errata, "enabled workaround for");
 }
+
+void __init enable_errata_workarounds(void)
+{
+    enable_cpu_capabilities(arm_errata);
+}
+
 /*
  * Local variables:
  * mode: C
index 088625bbacf89fece1daf614938cce5e3f4efc93..c1cd425067d7310bd8c83db023c25c8b62f9482c 100644 (file)
@@ -20,6 +20,7 @@
 #include <xen/types.h>
 #include <xen/init.h>
 #include <xen/smp.h>
+#include <xen/stop_machine.h>
 #include <asm/cpufeature.h>
 
 DECLARE_BITMAP(cpu_hwcaps, ARM_NCAPS);
@@ -40,6 +41,34 @@ void update_cpu_capabilities(const struct arm_cpu_capabilities *caps,
     }
 }
 
+/*
+ * Run through the enabled capabilities and enable() it on all active
+ * CPUs.
+ */
+void __init enable_cpu_capabilities(const struct arm_cpu_capabilities *caps)
+{
+    for ( ; caps->matches; caps++ )
+    {
+        if ( !cpus_have_cap(caps->capability) )
+            continue;
+
+        if ( caps->enable )
+        {
+            int ret;
+
+            /*
+             * Use stop_machine_run() as it schedules the work allowing
+             * us to modify PSTATE, instead of on_each_cpu() which uses
+             * an IPI, giving us a PSTATE that disappears when we
+             * return.
+             */
+            ret = stop_machine_run(caps->enable, (void *)caps, NR_CPUS);
+            /* stop_machine_run should never fail at this stage of the boot. */
+            BUG_ON(ret);
+        }
+    }
+}
+
 /*
  * Local variables:
  * mode: C
index e9ec4f4b79ed78148a3dfd6de759e3d8766984c7..3861f2d481cb24c2190c88547354840f9a11626e 100644 (file)
@@ -840,6 +840,8 @@ void __init start_xen(unsigned long boot_phys_offset,
 
     do_initcalls();
 
+    enable_errata_workarounds();
+
     /* Create initial domain 0. */
     /* The vGIC for DOM0 is exactly emulating the hardware GIC */
     config.gic_version = XEN_DOMCTL_CONFIG_GIC_NATIVE;
index c495ee5009cdc1af9447e8d6660762fef6ec9b81..5d66194fa714cc6b8901581ced44db90e1585aa0 100644 (file)
@@ -2,6 +2,7 @@
 #define __ARM_CPUERRATA_H__
 
 void check_local_cpu_errata(void);
+void enable_errata_workarounds(void);
 
 #endif /* __ARM_CPUERRATA_H__ */
 /*
index 6ae90b4d693f73f4ec6a76a8c99c8b43376180ac..41528af497364c0732c4c619268ff8da077164b9 100644 (file)
@@ -66,6 +66,7 @@ struct arm_cpu_capabilities {
     const char *desc;
     u16 capability;
     bool_t (*matches)(const struct arm_cpu_capabilities *);
+    int (*enable)(void *); /* Called on every active CPUs */
     union {
         struct {    /* To be used for eratum handling only */
             u32 midr_model;
@@ -77,6 +78,8 @@ struct arm_cpu_capabilities {
 void update_cpu_capabilities(const struct arm_cpu_capabilities *caps,
                              const char *info);
 
+void enable_cpu_capabilities(const struct arm_cpu_capabilities *caps);
+
 #endif /* __ASSEMBLY__ */
 
 #endif