# DF-4906 — READ_PENDING_WAIT spins forever on a stuck FID/VID "change pending" bit

**File:** `sys/dev/powermng/powernow/powernow.c:84-87` (used at 263, 275, 293, 299, 306)
**Severity:** Low · **Bucket:** base:dev · **Confidence:** certain (code) / speculative (trigger)

## Root cause

```c
#define READ_PENDING_WAIT(status)                               \
        do {                                                    \
                (status) = rdmsr(MSR_AMDK7_FIDVID_STATUS);      \
        } while (PN8_STA_PENDING(status))                       /* powernow.c:84-87 */
```

Every step of the fid/vid transition in `k8_powernow_setperf()` ends in
this unbounded do/while.  If the CPU's FID/VID status "change pending"
bit (MSR 0xc0010042 bit 31) never clears — stuck due to silicon erratum,
a wedged PLL, or incomplete VM MSR emulation — the calling thread spins
at full tilt forever in kernel context; nothing preempts a
`rdmsr`-test loop that never sleeps and never checks signals.

The driver's own comment (powernow.c:235-238) acknowledges the hazard —
*"need to ensure that the change pending bit isn't stuck"* — and then
proceeds to use the unbounded macro at all five wait points
(powernow.c:263, 275, 293, 299, 306).  Linux's powernow-k8 equivalent
checks the pending bit once and returns `-EIO` instead of spinning.

Consequences: one CPU pegged at 100% in kernel; the sysctl write thread
is unkillable (never reaches a sleep/checkpoint); on the module-load
path (powernow_init:392 → setperf) the boot kldload wedges.  Local DoS
only; requires root-triggered frequency change or the module-load path,
plus a misbehaving CPU/firmware.

## Verification status

`untested` — requires AMD K8 hardware with a stuck pending bit; the
audit guest is Intel/QEMU and the module's CPUID gate refuses
(`MOD_LOAD error 2`, env.txt).

## Recommended fix

Bound the wait (e.g. loop with a deadline; on timeout abort the
transition with an error) — see `fix.diff`.
