# DF-3613 — Integer divide-by-zero on zero PLL reference clock from VBIOS FirmwareInfo (si_dpm.c:4811 do_div, :4927 mpll divide)

**Severity:** Medium  **Confidence:** certain  **Status:** reproduced (harness)
**Impact:** panic

## What

radeon_atom_get_clock_info stores usCoreReferenceClock/usMemoryReferenceClock into spll/mpll.reference_freq with no zero fallback (pll_out_min gets a 64800/20000 default at radeon_atombios.c:1202, the reference clocks do not). si_calculate_sclk_params:4811 does do_div(tmp, reference_clock) for EVERY performance level of every power state (and 256x from si_init_smc_spll_table:2866) during si_dpm_enable; si_populate_mclk_value:4927 divides freq_nom by the mpll reference. reference_freq==0 -> #DE -> panic on the first level upload. Harness executes the exact 64-bit division in a forked child: SIGFPE == kernel #DE panic.

## Reproduce

```
sh build.sh   # cc -O2 -Wall -o harness harness.c
sh run.sh     # prints [A] buggy-path behaviour, [B] fixed-path behaviour
```

Expected decisive output (see run.log): the `[A]` section shows the fault or
corruption the kernel would take; the `[B]` section shows the behaviour with
fix.diff applied.

No AMD GPU is attached to the audit QEMU guest (virtio-only), so the radeon
DPM path cannot be exercised live; the harness replicates the exact kernel
expressions with crafted-VBIOS inputs (house methodology, cf. DF-1137..1140).

## Fix

`fix.diff` — validated: `git apply --check` clean; `make si_dpm.o` in
sys/dev/drm/radeon with KERNBUILDDIR=/usr/obj/usr/src/sys/X86_64_GENERIC
compiles -Werror clean with all five pass-2 fixes stacked; harness `[B]`
shows the primitive gone.
