DF-5155 / pbtest.c
/* * DF-5155 trigger — perfbias.c raw MSR pair on a CPUID-lying platform. * * Executes the exact instruction sequence of perfbias_set_handler() * (sys/dev/powermng/perfbias/perfbias.c:178-179): * * wrmsr(INTEL_MSR_PERF_BIAS, hint); // 0x1b0 * hint = rdmsr(INTEL_MSR_PERF_BIAS); * * First exercises the fault-safe variants (rdmsr_safe/wrmsr_safe) to show * what the recommended fix would see on a lying platform, then performs the * raw pair. On any CPU/VMM that sets CPUID.06H.ECX bit 3 (SETBH) without * implementing MSR 0x1b0, the raw wrmsr takes a fatal #GP in kernel mode * (Fatal trap 9) -> DDB -> system down. */ #include <sys/param.h> #include <sys/module.h> #include <sys/kernel.h> #include <sys/systm.h> #include <machine/cpufunc.h> #define INTEL_MSR_PERF_BIAS 0x1b0 static int pbtest_modevent(module_t mod, int type, void *data) { uint64_t val = 0; int error; switch (type) { case MOD_LOAD: kprintf("pbtest: rdmsr_safe(MSR_IA32_ENERGY_PERF_BIAS=0x1b0)...\n"); error = rdmsr_safe(INTEL_MSR_PERF_BIAS, &val); kprintf("pbtest: rdmsr_safe -> error %d, val %#llx\n", error, (unsigned long long)val); kprintf("pbtest: wrmsr_safe(0x1b0, 7)...\n"); error = wrmsr_safe(INTEL_MSR_PERF_BIAS, 7); kprintf("pbtest: wrmsr_safe -> error %d\n", error); kprintf("pbtest: raw wrmsr now (perfbias.c:178 path) -- expect #GP panic\n\n"); wrmsr(INTEL_MSR_PERF_BIAS, 7); /* perfbias.c:178 */ kprintf("pbtest: raw wrmsr survived\n"); val = rdmsr(INTEL_MSR_PERF_BIAS); /* perfbias.c:179 */ kprintf("pbtest: raw rdmsr -> %#llx\n", (unsigned long long)val); return 0; case MOD_UNLOAD: return 0; } return EOPNOTSUPP; } static moduledata_t pbtest_mod = { "pbtest", pbtest_modevent, NULL }; DECLARE_MODULE(pbtest, pbtest_mod, SI_SUB_DRIVERS, SI_ORDER_ANY); |