⬢ DragonFlyBSD Kernel Audit
DF-4780 / patchcpu.c
← back to finding ↓ download raw
/*
 * DF-4780 trigger helper: substitute the CPUID model advertisement so the
 * *stock, unmodified* corecstat.ko takes its "original Atom" (family 06h
 * model 0x36, sc_is_atom=1 sc_version=0) attach path on this QEMU guest
 * (real family 0x0F). The driver's own probe() whitelists model 0x36
 * (corecstat.c:189), so with this advertisement attach() MUST handle it.
 *
 * corecstat.c:424 does KKASSERT(sc->sc_version != 0) for exactly this
 * version -- the chip-representative CPU (cpu5 here) reaches it after
 * creating the package sensordev => kernel panic at driver attach.
 */
#include <sys/param.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <machine/md_var.h>

static u_int saved_cpu_id;

static int
patchcpu_modevent(module_t mod, int type, void *data)
{
	switch (type) {
	case MOD_LOAD:
		saved_cpu_id = cpu_id;
		/* family 06h, model 36h (Cedarview Atom), stepping 1 */
		cpu_id = 0x00030661;
		kprintf("patchcpu: cpu_id 0x%08x -> 0x%08x "
		    "(family 06h model 36h Atom)\n", saved_cpu_id, cpu_id);
		return (0);
	case MOD_UNLOAD:
		cpu_id = saved_cpu_id;
		kprintf("patchcpu: cpu_id restored to 0x%08x\n", cpu_id);
		return (0);
	}
	return (EOPNOTSUPP);
}

static moduledata_t patchcpu_mod = { "patchcpu", patchcpu_modevent, NULL };
DECLARE_MODULE(patchcpu, patchcpu_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);