DF-5620 / mwaitforce.c
/* * DF-5620 rig helper -- substitutes ONLY the missing CPUID advertisement. * * This QEMU 7.2 reports CPUID.05H.ECX = 0x2 (INTBRK) and masks * CPUID.01H:ECX.MON under TCG, so the stock acpi_cst_cx_mwait_setup() * (acpi_cstate_machdep.c:149-153) would bail with EOPNOTSUPP before ever * reaching the hint-validation/error-path code under test -- the * DF-5155/DF-5160 "VMM lies about CPUID" premise, constructed here * deliberately (same methodology as DF-5483 estforce.ko). * * cpu_feature2/cpu_mwait_feature are boot globals written by EVERY cpu's * identify_cpu() (identcpu.c:645/649), and the APs come up between * SI_BOOT2_START_APS and SI_SUB_DRIVERS, so a MOD_LOAD-time write is * clobbered. We therefore re-force both words from a SYSINIT at * SI_SUB_CONFIGURE/SI_ORDER_FIRST -- after all cpu idents, immediately * before acpi0/cpu_cst probe. Everything afterwards is the genuine stock * driver. * * NOTE: cpu_mwait_cx_info[] subcnts stay zero (cpu_mwait_attach() ran before * us and bailed), so every hint is "invalid" to cpu_mwait_hint_valid() -- * exactly the scenario under test (a REJECTED descriptor). The default idle * hook remains the static "sti; hlt" (machdep.c:1115); the ACPI idle hook * only ever selects the (valid) C1 halt state here, so the late feature * words cannot destabilize the boot idle path. */ #include <sys/param.h> #include <sys/module.h> #include <sys/kernel.h> #include <sys/systm.h> #include <machine/cputypes.h> #include <machine/md_var.h> #include <machine/specialreg.h> static void mwaitforce_force(void) { cpu_feature2 |= CPUID2_MON; cpu_mwait_feature |= CPUID_MWAIT_EXT | CPUID_MWAIT_INTBRK; kprintf("mwaitforce: cpu_feature2 |= MON (%#x), " "cpu_mwait_feature |= EXT|INTBRK (%#x)\n", cpu_feature2, cpu_mwait_feature); } static void mwaitforce_late(void *unused __unused) { /* After all AP identify_cpu()s, right before device configure(). */ mwaitforce_force(); } SYSINIT(mwaitforce_late, SI_SUB_CONFIGURE, SI_ORDER_FIRST, mwaitforce_late, NULL); static int mwaitforce_modevent(module_t mod, int type, void *data) { switch (type) { case MOD_LOAD: kprintf("mwaitforce: loaded (force happens at SI_SUB_CONFIGURE)\n"); return 0; case MOD_UNLOAD: return 0; } return EOPNOTSUPP; } static moduledata_t mwaitforce_mod = { "mwaitforce", mwaitforce_modevent, NULL }; DECLARE_MODULE(mwaitforce, mwaitforce_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); MODULE_VERSION(mwaitforce, 1); |