# DF-4153 — Zero VBIOS reference clocks stored unchecked reach PLL/SS divisions (#DE panic) — amdgpu twin of DF-3742

File: `sys/dev/drm/amd/amdgpu/amdgpu_atombios.c` (pass 2)

## Reproduced?

**No — hardware-gated** (no AMD GPU on the audit guest; see `env.txt`).
Established at source level.

## Source trace

`amdgpu_atombios_get_clock_info()` copies three BIOS-provided reference
clocks with no zero/validity check — unlike the neighboring limits which
*are* defaulted (`pll_out_min == 0 → 64800` at `:610-611`, `:642-643`,
`:669-670`, `max_pixel_clock == 0 → 40000` at `:708-709`):

```c
592:  ppll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock);
632:  spll->reference_freq = le16_to_cpu(firmware_info->info_21.usCoreReferenceClock);
659:  mpll->reference_freq = le16_to_cpu(firmware_info->info_21.usMemoryReferenceClock);
```

`ppll[0..AMDGPU_MAX_PPLL-1]` are populated by the struct copy at `:628-629`,
and `adev->pm.current_sclk/mclk` derive from the same table (`:677-719`).

Downstream divisions with no intervening zero check (grep for
`reference_freq == 0` across `sys/dev/drm/amd/amdgpu/` finds nothing):

1. **Mode set / PLL compute** — `amdgpu_pll.c:187` `den = pll->reference_freq`
   (for pixel PLLs = `ppll[].reference_freq`), then
   `amdgpu_pll.c:92` `*fb_div = DIV_ROUND_CLOSEST(nom * *ref_div * post_div, den)`
   → integer division by zero (`gcd(nom,0)` at `:50` is safe — the libkern
   `while (b)` loop skips — but `den` survives as 0 to `:92`).
   Every CRTC mode program via `amdgpu_pll_compute` reaches this.
2. **Spread-spectrum step size** — `atombios_crtc.c:876` and `:879`:
   `step_size = (...) / (125 * 25 * pll->reference_freq / 100);` — the
   denominator collapses to 0 when `reference_freq == 0` → #DE during
   `amdgpu_atombios_crtc_program_pll` when SS is enabled (SS comes from the
   same VBIOS, `amdgpu_atombios_get_asic_ss_info`).
3. DPM-side consumers (`si_dpm.c:5257/5379`, `ci_dpm.c:2122/2970/3313`,
   `cik.c:842-851`, `vi.c:328-342`) propagate the zero into clock
   conversions with further divides.

Sibling (noted, different file): `amdgpu_atomfirmware.c:290/313` sets the
same fields from atomfirmware tables, also unchecked.

Trigger: crafted VBIOS with `usReferenceClock == 0` (or the
`info_21` fields for sclk/mclk paths) — driver attach succeeds; first mode
set (or DPM init) faults with a kernel divide error → local DoS / panic.
This is exactly the pattern accepted as Medium for radeon (DF-3742).

## Verdict

INCONCLUSIVE (hardware-gated / not reachable on the audit guest).
Source-certain: unchecked zero reaches at least two concrete division sites.
Severity Medium (crafted-VBIOS local DoS via panic; hardware-gated delivery).

## 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.
