{
update_cpu_capabilities(arm_errata, "enabled workaround for");
}
+
+void __init enable_errata_workarounds(void)
+{
+ enable_cpu_capabilities(arm_errata);
+}
+
/*
* Local variables:
* mode: C
#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);
}
}
+/*
+ * 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
* stop_machine (tasklets initialized via an initcall).
*/
apply_alternatives_all();
+ enable_errata_workarounds();
/* Create initial domain 0. */
/* The vGIC for DOM0 is exactly emulating the hardware GIC */
#include <asm/alternative.h>
void check_local_cpu_errata(void);
+void enable_errata_workarounds(void);
#ifdef CONFIG_HAS_ALTERNATIVE
const char *desc;
u16 capability;
bool (*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;
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