DF-5623 / pstprobe.c
/* * pstprobe.c -- live introspection KLD for the pass-2 audit of * sys/platform/pc64/x86_64/cpufreq_machdep.c (DF-5622/DF-5623 evidence). * * Safe by construction: only calls acpi_pst_md_probe() (pure CPUID/global * reads; no MSR access anywhere in the probe path) and prints addresses of * the amd0f_* helper symbols compiled into the running GENERIC kernel. * * NEVER calls amd0f_set_fidvid/amd0f_get_fidvid/amd0f_fidvid_limit: * they begin with rdmsr(0xc0010042) which raises #GP on non-AMD-0F CPUs * (that is the DF-5484 class, not what we are probing here). */ #include <sys/param.h> #include <sys/kernel.h> #include <sys/systm.h> #include <sys/module.h> #include <machine/md_var.h> /* cpu_vendor_id, cpu_id, cpu_exthigh */ #include <machine/cpufunc.h> /* do_cpuid */ #include <machine/specialreg.h> /* CPUID_TO_FAMILY, CPUID_TO_MODEL */ #include <machine/cpufreq.h> /* amd0f_* prototypes */ /* global in acpi_pstate_machdep.c, no public header */ const struct acpi_pst_md *acpi_pst_md_probe(void); /* minimal local mirror of struct acpi_pst_md (sys/dev/acpica/acpi_cpu_pstate.h): * five function pointers; only pmd_set_pstate (3rd) is dereferenced, guarded */ struct pst_md_probe_view { void *pmd_check_csr; void *pmd_check_pstates; void *pmd_set_pstate; void *pmd_get_pstate; void *pmd_init; }; static void pstprobe_load(void *dummy __unused) { const struct acpi_pst_md *md; uint32_t regs[4]; kprintf("pstprobe: cpu_vendor_id=%#x (AMD=%#x INTEL=%#x) " "family=%#x model=%#x\n", cpu_vendor_id, CPU_VENDOR_AMD, CPU_VENDOR_INTEL, CPUID_TO_FAMILY(cpu_id), CPUID_TO_MODEL(cpu_id)); /* exact gate from acpi_pstate_machdep.c:acpi_pst_amd_probe() */ if (cpu_exthigh >= 0x80000007) { do_cpuid(0x80000007, regs); kprintf("pstprobe: APMI(0x80000007) edx=%#x " "(amd0f needs (edx & 0x06) == 0x06)\n", regs[3]); } else { kprintf("pstprobe: no 0x80000007 leaf (cpu_exthigh=%#x) " "-> amd0f probe returns NULL\n", cpu_exthigh); } md = acpi_pst_md_probe(); if (md == NULL) { kprintf("pstprobe: acpi_pst_md_probe() = NULL: no P-state " "machdep; acpi_pst_amd0f ops NEVER selected -> " "amd0f_set_fidvid UNREACHABLE on this CPU\n"); } else { const struct pst_md_probe_view *v = (const struct pst_md_probe_view *)md; kprintf("pstprobe: acpi_pst_md_probe() = %p " "pmd_set_pstate=%p (amd0f backend would be a static fn " "calling amd0f_set_fidvid=%p)\n", md, v->pmd_set_pstate, &amd0f_set_fidvid); } kprintf("pstprobe: symbols in running kernel: " "amd0f_set_fidvid=%p amd0f_get_fidvid=%p amd0f_fidvid_limit=%p\n", &amd0f_set_fidvid, &amd0f_get_fidvid, &amd0f_fidvid_limit); } SYSINIT(pstprobe, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE, pstprobe_load, NULL); static int pstprobe_modevent(module_t mod __unused, int type, void *data __unused) { switch (type) { case MOD_LOAD: /* SYSINIT above runs at SI_SUB_CONFIGURE; nothing here */ return 0; default: return EOPNOTSUPP; } } static moduledata_t pstprobe_mod = { "pstprobe", pstprobe_modevent, NULL }; DECLARE_MODULE(pstprobe, pstprobe_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); MODULE_VERSION(pstprobe, 1); |