DF-5484 / msrprobe.c
/* * DF-5484 probe -- which of the fixed P-state MSRs does this VMM actually * implement? Exercises the fault-safe accessors ONLY (no raw ops, no * panic). The audited file sys/platform/pc64/acpica/acpi_pstate_machdep.c * touches these MSRs with RAW rdmsr()/wrmsr(): * * Intel: 0x1a0 (MISC_ENABLE, acpi_pst_intel_init :506/:509/:511) * 0x199 (PERF_CTL, acpi_pst_intel_set_pstate :530/:533) * 0x198 (PERF_STATUS, acpi_pst_intel_get_pstate :555) * AMD: 0xc0010062/63/64.. amd1x paths (:227/:259/:280) * * If rdmsr_safe()/wrmsr_safe() return an error here while CPUID advertises * the feature (EST for Intel), the driver's raw accessors would have taken * a fatal #GP instead (DF-4735/DF-5155/DF-5160 class). */ #include <sys/param.h> #include <sys/module.h> #include <sys/kernel.h> #include <sys/systm.h> #include <machine/cpufunc.h> #include <machine/specialreg.h> #define INTEL_MSR_MISC_ENABLE 0x1a0 #define INTEL_MSR_PERF_STATUS 0x198 #define INTEL_MSR_PERF_CTL 0x199 #define AMD1X_MSR_PSTATE_CTL 0xc0010062 #define AMD1X_MSR_PSTATE_ST 0xc0010063 #define AMD1X_MSR_PSTATE_START 0xc0010064 static void probe_one(const char *name, u_int msr, int wr) { uint64_t val = 0; int error; error = rdmsr_safe(msr, &val); kprintf("msrprobe: %-14s rdmsr_safe(0x%04x) -> error %d, val %#llx\n", name, msr, error, (unsigned long long)val); if (error == 0 && wr) { error = wrmsr_safe(msr, val); /* write back same value */ kprintf("msrprobe: %-14s wrmsr_safe(0x%04x, same) -> error %d\n", name, msr, error); } } static int msrprobe_modevent(module_t mod, int type, void *data) { switch (type) { case MOD_LOAD: kprintf("msrprobe: cpu_vendor_id %d cpu_id %#x " "cpu_feature2 %#x (CPUID2_EST %s)\n", cpu_vendor_id, cpu_id, cpu_feature2, (cpu_feature2 & CPUID2_EST) ? "SET" : "clear"); probe_one("intel misc_en", INTEL_MSR_MISC_ENABLE, 1); probe_one("intel perf_st", INTEL_MSR_PERF_STATUS, 0); probe_one("intel perf_ctl", INTEL_MSR_PERF_CTL, 1); probe_one("amd pst_ctl", AMD1X_MSR_PSTATE_CTL, 0); probe_one("amd pst_st", AMD1X_MSR_PSTATE_ST, 0); probe_one("amd pst_0", AMD1X_MSR_PSTATE_START, 0); return 0; case MOD_UNLOAD: return 0; } return EOPNOTSUPP; } static moduledata_t msrprobe_mod = { "msrprobe", msrprobe_modevent, NULL }; DECLARE_MODULE(msrprobe, msrprobe_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); MODULE_VERSION(msrprobe, 1); |