# DF-3986 VERDICT — dropped CP1/CP2 ring init in cayman_init (ni.c)

**Status: inconclusive (hardware-gated: no AMD Northern-Islands GPU on the
audit guest — vgapci is QEMU std VGA, env evidence in ../DF-3981/env.txt).
Source-level certainty: certain (divergence provable in-tree).**

## Divergence proof

Consumers of CP1/CP2 ring state in this file:
- `cayman_cp_resume` ridx[] = {GFX, CP1, CP2} (ni.c:1636-1640) iterates all
  three: `rb_cntl = order_base_2(ring->ring_size / 8)` (ni.c:1704),
  `WREG32(cp_rb_base[i], ring->gpu_addr >> 8)` (ni.c:1720);
- `radeon_fence_driver_start_ring(CP1)` / `(CP2)` (ni.c:2225, 2231);
- `ready = false` for both at ni.c:1739-1740.

Producers: `cayman_init` calls `r600_ring_init` only for GFX (1 MB) and
DMA0/DMA1 (64 KB) (ni.c:2434-2443). `r600_ring_init` (r600.c:2789-2807) is
the only setter of `ring->ring_size` before resume; CP1/CP2 therefore
reach `cayman_cp_resume` with `ring_size == 0` and `gpu_addr == 0`.

Upstream Linux ni.c initializes all five rings (GFX/CP1/CP2 at 1 MB,
DMA0/DMA1 at 64 KB) in `cayman_init`; the in-tree siblings `si.c`
(si.c:6876-6894) and `cik.c` (cik.c:8655-8679) do the same for their
compute rings. The DFly port dropped exactly the two CP blocks.

## UB and misprogramming

`order_base_2(n) = ilog2(roundup_pow_of_two(n))`
(sys/dev/drm/include/linux/log2.h:100 and :33-36):
`roundup_pow_of_two(0) = 1UL << flsl(0 - 1) = 1UL << flsl(ULONG_MAX) =
1UL << 64` — shift count equals the width of `unsigned long`: undefined
behavior per C11 6.5.7. On x86-64 the compiler emits `shl` which masks the
count mod 64, yielding 1 → `order_base_2(0) == 0` → RB_BUFSZ field 0 with
ring base 0 programmed into CP_RB1/CP_RB2 at every Cayman/Aruba boot
(functionally meaningless config; compute rings never enabled since
`ready=false`).

## Why no memory-safety impact

- `radeon_cs_get_ring` (radeon_cs.c:203-234): COMPUTE → CP1/CP2 only for
  `family >= CHIP_TAHITI`; CAYMAN/ARUBA (< TAHITI) map COMPUTE to GFX.
- `radeon_ring_alloc` (radeon_ring.c:104-137) fails `-ENOMEM` for any
  `ndw > ring->ring_size/4`, so a zero-sized ring cannot be written.
- `radeon_ring_supports_scratch_reg`/debugfs only read the ring array.

Residual: C-standard UB in the boot path + wrong MMIO values + compute
rings permanently unusable on this family in this port (upstream supports
compute on Cayman). Info severity.

## Fix validation
Not runnable (no AMD GPU in the guest; `vgapci0` is `1234:1111` QEMU VGA).
fix.diff restores the two upstream init blocks verbatim.

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