# DF-5005 — amdgpu_atombios_get_clock_info() accepts usReferenceClock==0 → guaranteed amdgpu_pll_compute div0

`sys/dev/drm/amd/amdgpu/amdgpu_atombios.c:592-593`:

    ppll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock);

is copied from the VBIOS `FirmwareInfo` table **without any zero check**, even
though the *same function* fixes up every neighbouring field that can be 0:
`pll_out_min → 64800` (:610-611), `lcd_pll_out_min/max → pll_out_*` (:603-608),
`spll/mpll pll_out_min → 64800` (:642-643, :669-670), `max_pixel_clock →
40000` (:708-709). `reference_freq` is the odd one out — this is exactly the
"latent reference_freq==0 div0" lead from the rs400/r100 family.

The value is installed into `ppll[0]` and cloned into every `ppll[1..]`
(:628-629); every pixel-clock programming path then feeds it to
`amdgpu_pll_compute()` (atombios_crtc.c:835-854 → amdgpu_pll.c:187
`den = pll->reference_freq`). With `reference_freq == 0`:

* `amdgpu_pll_reduce_ratio()`: `gcd(nom, 0) = nom` → `den = 0`; the
  denominator-minimum fixup then executes `DIV_ROUND_UP(den_min, 0)` →
  **divide by zero panic at amdgpu_pll.c:63** on the *first modeset* with any
  nonzero clock;
* (if the mode clock is also 0: `gcd(0,0) = 0` → `*nom /= 0` at :51);
* sibling sink: spread-spectrum step-size math divides by
  `pll->reference_freq / 100` (atombios_crtc.c:875-879) — `reference_freq <
  100` gives another zero divisor on the same path.

Same for the spll/mpll copies (:632-633, :659-660: `usCoreReferenceClock`,
`usMemoryReferenceClock`) which feed the DPM PLL calculators.

## Reproduce

Same harness as DF-5004 (verbatim `amdgpu_pll.c` function copies):

    cc -g -O0 -Wall -o pll_harness pll_harness.c
    ./pll_harness ref0      # SIGFPE at amdgpu_pll.c:63 (gdb_lines.txt)
    ./pll_harness control   # sanity: 27 MHz reference completes fine

gdb pins the trap to `pll_harness.c:114` == `amdgpu_pll.c:63`
(`tmp = DIV_ROUND_UP(den_min, *den)` with `den == 0`, frame shows
`nom_min=4, den_min=11` — `den_min` is `post_div_min=ceil(64800/6000)=11`,
proving the zero is the reference frequency, not the mode clock).

## Threat model

The zero comes from the VBIOS/ATOM firmware image (corrupt or malicious
VBIOS, or a driver bug leaving the field unset when `get_clock_info` is
skipped), not from runtime user input — unlike DF-2037/DF-5004. Impact is a
deterministic kernel panic at first display configuration (firmware
robustness / secure-boot supply-chain angle), hence **Low**.

## Fix

`fix.diff` — give `reference_freq` the same `==0` fixup its sibling fields
already get (27 MHz default for ppll; spll/mpll similarly), plus harden the
consumer (`amdgpu_pll.c` guards, DF-5004's fix.diff).
