⬢ DragonFlyBSD Kernel Audit
DF-4735 / msrtest.c
← back to finding ↓ download raw
/*
 * DF-4735 trigger: prove that on a VMM which advertises CPUID.06H DTS
 * without virtualizing MSR_THERM_STATUS, coretemp's raw rdmsr(0x19c)
 * (coretemp.c:599) takes an unrecoverable #GP in kernel context.
 * On this guest KVM masks the DTS bit (leaf6 EAX=0x4 ARAT only), so
 * coretemp_identify never attaches; this module reproduces what the
 * sensor task would do 2s after boot on a DTS-advertising VMM.
 */
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/module.h>
#include <machine/cpufunc.h>
#include <machine/specialreg.h>

static int
msrtest_modevent(module_t mod, int type, void *data)
{
	uint64_t msr;
	int error;

	switch (type) {
	case MOD_LOAD:
		kprintf("msrtest: rdmsr_safe(MSR_THERM_STATUS=0x19c)...\n");
		error = rdmsr_safe(MSR_THERM_STATUS, &msr);
		if (error) {
			kprintf("msrtest: rdmsr_safe -> error %d (MSR faults on "
			    "this VMM)\n", error);
			kprintf("msrtest: raw rdmsr now (coretemp.c:599 path) "
			    "-- expect #GP panic\n");
		} else {
			kprintf("msrtest: rdmsr_safe -> ok 0x%llx\n",
			    (unsigned long long)msr);
			kprintf("msrtest: raw rdmsr now for completeness\n");
		}
		msr = rdmsr(MSR_THERM_STATUS);
		kprintf("msrtest: raw rdmsr survived: 0x%llx\n",
		    (unsigned long long)msr);
		return 0;
	default:
		return 0;
	}
}

static moduledata_t msrtest_mod = { "msrtest", msrtest_modevent, NULL };
DECLARE_MODULE(msrtest, msrtest_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);