# DF-4906 — VERDICT

**status: untested · reproduced: 0 · impact: dos (unkillable kernel spin) · confidence: speculative (code certain)**

## Narrative

All five wait points in the fid/vid transition sequence end with the
`READ_PENDING_WAIT` macro (powernow.c:84-87) — an unbounded
`do { rdmsr; } while (pending)` loop.  Nothing in the loop sleeps,
checks signals, or times out; a FID/VID status register whose
change-pending bit (bit 31) never clears therefore spins the calling
thread at 100% in kernel context forever:

* sysctl-write path (`machdep.powernow.frequency.target`,
  powernow.c:323-335): unkillable thread, one CPU lost;
* module-load path (powernow_init:392 → setperf): kldload wedges.

The developer comment at powernow.c:235-238 explicitly flags the stuck
pending bit as a case to guard, but the macro provides no guard.  The
upstream Linux powernow-k8 driver checks the pending bit once and
propagates `-EIO`.

## Verification

Not runtime-testable: needs an AMD K8 whose pending bit sticks (silicon
erratum / hostile VM MSR emulation).  The Intel/QEMU audit guest refuses
the module at the CPUID gate (`MOD_LOAD error 2`, env.txt) before any
MSR access.  Analysis pack only.

## Fix

`fix.diff`: bounded loop (1e6 iterations, `DELAY(1)` between polls).
Applies cleanly.  Callers already tolerate the macro not forcing an
error return; a full fix should also abort the transition on timeout.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
