# DF-3613 — Verdict

## Verdict: REPRODUCED (source-level + harness) — integer divide-by-zero (#DE) panic from zero PLL reference clock

Distinct div0 sink from DF-1137 (fan) and DF-3612 (SS rate): the divisor is
the FirmwareInfo PLL reference clock.

## Bug confirmation

```c
radeon_atombios.c:1188-1193  /* system clock */  [SI is DCE6 -> DCE4 branch]
    spll->reference_freq = le16(firmware_info->info_21.usCoreReferenceClock);  // no fallback
radeon_atombios.c:1215-1220  /* memory clock */
    mpll->reference_freq = le16(firmware_info->info_21.usMemoryReferenceClock); // no fallback
```

Contrast `pll_out_min`, which DOES get a default when 0
(radeon_atombios.c:1173-1178, 1202-1207, 1229-1234) — the reference clocks
were simply forgotten. si_dpm.c divides by them unconditionally:

```c
si_dpm.c:4798   u32 reference_clock = rdev->clock.spll.reference_freq;
si_dpm.c:4810   tmp = (u64)engine_clock * reference_divider * dividers.post_div * 16384;
si_dpm.c:4811   do_div(tmp, reference_clock);        // ==0 -> #DE

si_dpm.c:4920   u32 reference_clock = rdev->clock.mpll.reference_freq;
si_dpm.c:4927   tmp = freq_nom / reference_clock;    // ==0 -> #DE
```

`si_calculate_sclk_params` is called for every level of every power state
(`si_populate_sclk_value`) and 256 times from `si_init_smc_spll_table`
(si_dpm.c:2866) — i.e. always, on the first sclk programming of
`si_dpm_enable`.

## Harness confirmation

`run.log`:

```
[A1] si_dpm.c:4811 do_div(tmp, spll.reference_freq==0)
     child died from SIGFPE (signal 4): 64-bit divide by zero
[A2] si_dpm.c:4927 freq_nom / (mpll.reference_freq==0)
     child died from SIGFPE (signal 4): 64-bit divide by zero
[B]  ref=0  -> rc=-1 (level upload refused, no trap)
     ref=27000 -> rc=0, fbdiv=114081 (normal programming)
```

## Trigger conditions (not met on this guest)

SI GPU + radeon DPM (virtio-only guest) + FirmwareInfo with
usCoreReferenceClock == 0 (or usMemoryReferenceClock == 0 for the mclk sink).

## Exploit chain

None — #DE; boot-time DoS panic.

## Fix

`fix.diff` — `if (reference_clock == 0) return -EINVAL;` at the top of both
consumers (si_calculate_sclk_params, si_populate_mclk_value). Validation:
apply-check OK; `make si_dpm.o` -Werror clean (stacked); harness `[B]`
refuses the zero-clock case while the sane-clock arithmetic is unchanged.

`fix_status: fixed` (compile + harness-level).

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