# DF-4735 — coretemp sensor task reads MSR_THERM_STATUS/MSR_PKG_THERM_STATUS with raw rdmsr; a CPUID-lying platform (VMM) turns the stock kernel's 2-second sensor tick into an unrecoverable #GP panic

**File**: `sys/dev/powermng/coretemp/coretemp.c:599-601` (fetch), `:279` (EXT_CONFIG), `:306` (the safe read used 20 lines above)
**Severity**: Low (DoS/panic; needs a DTS-advertising platform without the MSR) — **likely** (mechanism guest-proven; see below).
**GUEST-REPRODUCED consequence**: yes — raw `rdmsr(0x19c)` in kernel context → `Fatal trap 9: general protection fault` → DDB, guest down (`panic.txt`).

## Root cause
`coretemp_msr_fetch` uses the faulting form:

```c
599:	*msr = rdmsr(MSR_THERM_STATUS);
600:	if (pkg_msr != NULL)
601:		*pkg_msr = rdmsr(MSR_PKG_THERM_STATUS);
```

while the same file already acknowledges, twice, that CPUID can lie about thermal
capability:

- `coretemp.c:192-196` (identify): *"Some Intel CPUs, namely the PIII, don't have
  thermal sensors, but report them in cpu_thermal_feature. This leads to a later GPF
  when the sensor is queried via a MSR, so we stop here."* — the `model >= 0xe`
  whitelist is the only thing standing between that documented GPF and the MSR read.
- `coretemp.c:306` (attach): uses `rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &msr)`
  because TEMPERATURE_TARGET is not guaranteed either.

So the driver's own comments/code establish "CPUID thermal bits are unreliable", yet the
two MSRs read from the **periodic sensor task** (registered at `coretemp.c:455-464`,
fires every 2 s on the pinned CPU) use the raw faulting read. On any platform where
CPUID.06H advertises DTS/PTM without implementing the MSRs, a stock
`X86_64_GENERIC` kernel (`device coretemp`, config:188) panics ~2 s after boot with no
user interaction. Upstream FreeBSD re-engineered exactly this path (live `do_cpuid(0x06)`
re-check in identify + fault-safe `x86_msr_op` reads), confirming the class.

## What was proven on the guest (the honest chain)
1. Stock guest CPU (`qemu64` under KVM): leaf 6 EAX = 0 → `coretemp_identify` exits at
   `coretemp.c:200-201` → coretemp never attaches (inert in-kernel module). This is the
   **only** reason the stock guest doesn't panic.
2. Rebooted the guest with `-cpu host` (Intel Xeon E3-1275 v5 / Skylake host):
   CPUID leaf 6 EAX = **0x4 (ARAT) — KVM deliberately strips the DTS bit even on
   host-passthrough** (`sysctl -a | grep Thermal` → `Thermal and PM Features=0x4<ARAT>`).
   identify still gated out. KVM strips the bit *because* it does not virtualize the MSR.
3. Loaded `msrtest.ko` (this pack) which executes the exact `coretemp.c:599`
   instruction in kernel context:
   - `rdmsr_safe(MSR_THERM_STATUS)` → **error 14** (MSR faults on this VMM);
   - raw `rdmsr(MSR_THERM_STATUS)` → **Fatal trap 9: general protection fault while in
     kernel mode … Stopped at msrtest_modevent+0x5d: rdmsr** (`panic.txt`).

So: on any VMM that *does* advertise the DTS bit without virtualizing the MSR (the
"lying CPUID" platform class the driver itself documents for PIII, and which KVM's
masking policy proves VMM vendors anticipate), the stock kernel panics in
`coretemp_msr_fetch` two seconds after boot. The trigger module substitutes only the
CPUID advertisement (root-only kldload); no user-space action is required on an
affected platform.

## Reproduce
```
# build (on guest):
mkdir /tmp/msrmod && cp msrtest.c /tmp/msrmod/ && cd /tmp/msrmod
printf 'KMOD=\tmsrtest\nSRCS=\tmsrtest.c\n\n.include <bsd.kmod.mk>\n' > Makefile
make SYSDIR=/usr/src/sys
# run (guest must be on a CPU where MSR 0x19c faults — e.g. KVM, any cpu model):
kldload /tmp/msrmod/msrtest.ko
# expected: rdmsr_safe -> error 14; then
#   Fatal trap 9: general protection fault while in kernel mode
#   Stopped at msrtest_modevent+0x5d:  rdmsr      (db> prompt, guest dead)
```

## Fix
`fix.diff`: `coretemp_msr_fetch` becomes fault-safe (`rdmsr_safe`, returns error), and
both sensor tasks map a failed fetch to `CORETEMP_TEMP_INVALID` (sensors go invalid —
exactly the amdtemp/FreeBSD semantics). Build-validated with the same nativekernel run
as DF-4733/4734; the baseline run itself demonstrates the fix's degradation path
(`rdmsr_safe` → error 14, no trap).
