cpumask_andnot(mask, mask, &target);
}
+/* Force sending of a wakeup IPI regardless of mwait usage. */
+bool __ro_after_init force_mwait_ipi_wakeup;
+
bool arch_skip_send_event_check(unsigned int cpu)
{
+ if ( force_mwait_ipi_wakeup )
+ return false;
+
/*
* This relies on softirq_pending() and mwait_wakeup() to access data
* on the same cache line.
#include <asm/intel-family.h>
#include <asm/processor.h>
#include <asm/msr.h>
+#include <asm/mwait.h>
#include <asm/uaccess.h>
#include <asm/mpspec.h>
#include <asm/apic.h>
INTEL_FAM6_MODEL(0x25),
{ }
};
-#undef INTEL_FAM6_MODEL
/* Serialized by the AP bringup code. */
if ( max_cstate > 1 && (c->apicid & (c->x86_num_siblings - 1)) &&
}
}
+/*
+ * APL30: One use of the MONITOR/MWAIT instruction pair is to allow a logical
+ * processor to wait in a sleep state until a store to the armed address range
+ * occurs. Due to this erratum, stores to the armed address range may not
+ * trigger MWAIT to resume execution.
+ *
+ * ICX143: Under complex microarchitectural conditions, a monitor that is armed
+ * with the MWAIT instruction may not be triggered, leading to a processor
+ * hang.
+ *
+ * LNL030: Problem P-cores may not exit power state Core C6 on monitor hit.
+ *
+ * Force the sending of an IPI in those cases.
+ */
+static void __init probe_mwait_errata(void)
+{
+ static const struct x86_cpu_id __initconst models[] = {
+ INTEL_FAM6_MODEL(INTEL_FAM6_ATOM_GOLDMONT), /* APL30 */
+ INTEL_FAM6_MODEL(INTEL_FAM6_ICELAKE_X), /* ICX143 */
+ INTEL_FAM6_MODEL(INTEL_FAM6_LUNARLAKE_M), /* LNL030 */
+ { }
+ };
+#undef INTEL_FAM6_MODEL
+
+ if ( boot_cpu_has(X86_FEATURE_MONITOR) && x86_match_cpu(models) )
+ {
+ printk(XENLOG_WARNING
+ "Forcing IPI MWAIT wakeup due to CPU erratum\n");
+ force_mwait_ipi_wakeup = true;
+ }
+}
+
/*
* P4 Xeon errata 037 workaround.
* Hardware prefetcher may cause stale data to be loaded into the cache.
__set_bit(X86_FEATURE_CLFLUSH_MONITOR, c->x86_capability);
probe_c3_errata(c);
+ if (system_state < SYS_STATE_smp_boot)
+ probe_mwait_errata();
}
#define MWAIT_ECX_INTERRUPT_BREAK 0x1
+/* Force sending of a wakeup IPI regardless of mwait usage. */
+extern bool force_mwait_ipi_wakeup;
+
void mwait_idle_with_hints(unsigned int eax, unsigned int ecx);
bool mwait_pc10_supported(void);