# VERDICT DF-4578 — gfx8 KFD backend dead on DragonFly; latent index/NULL hazards

**Status: untested (no PoC is applicable — the dead-code claim itself is the verified fact).**
Severity Info, confidence certain. Mirror of DF-4499 (gfx_v9) for the gfx8 backend.

## What was verified, and how

1. **Dead code — certain.**
   - `sys/dev/drm/amd/amdgpu/Makefile:155-156`: `# add amdkfd interfaces` block adds
     `SRCS+= amdgpu_amdkfd.c` only. `amdgpu_amdkfd_gfx_v8.c` appears in no Makefile
     in the tree (checked `sys/dev/drm/amd/Makefile`, `sys/dev/drm/amd/amdgpu/Makefile`,
     `sys/dev/drm/Makefile`); SRCS lists are explicit enumerations, no wildcards.
     **The translation unit is never compiled into drm.ko/amdgpu.ko.**
   - `grep -rn "CONFIG_HSA_AMD" sys/` → only `#ifdef/#ifndef` guards
     (amdgpu_amdkfd.c:38,524; amdgpu_drv.c:553,1383); nothing defines it.
     `amdgpu_amdkfd_init()` (amdgpu_amdkfd.c:34-47) therefore forces
     `kgd2kfd = NULL; ret = -ENOENT;`.
   - `amdgpu_amdkfd_device_probe()` (amdgpu_amdkfd.c:57-71) returns before the
     CHIP_CARRIZO/TONGA/FIJI/POLARIS10/11 case that would call
     `amdgpu_amdkfd_gfx_8_0_get_functions()`. The linked symbol is the
     `#ifndef CONFIG_HSA_AMD` stub at amdgpu_amdkfd.c:554-557 returning NULL.
   - No `amd/amdkfd/` frontend exists in the tree (only the four
     `amdgpu_amdkfd*.[ch]` glue files): no `/dev/kfd`, no kfd ioctls, no queue
     manager — nothing can invoke the `kfd2kgd` table even if it were reachable.
   - Guest (env.txt): no 0x1002 PCI devices (virtio-gpu only), `/dev/dri` absent,
     no drm KLDs loaded — no runtime path either.

2. **Latent hazards (unreachable today; guard when enabling) — certain by inspection.**
   - `kgd_set_pasid_vmid_mapping` gfx_v8.c:245-270: unvalidated vmid →
     `mmATC_VMID0_PASID_MAPPING + vmid` (:260) / `mmIH_VMID_0_LUT + vmid` (:267)
     OOB MMIO writes past 16-entry banks; `1U << vmid` (:262) UB at vmid≥32;
     unbounded `cpu_relax()` poll (:262-263) = permanent thread wedge on GPU hang.
   - `get_atc_vmid_pasid_mapping_valid/pasid` gfx_v8.c:702-720: `uint8_t vmid`
     unchecked → OOB MMIO read up to +255 dwords.
   - `get_fw_version` gfx_v8.c:778-833: `fw->data` dereferenced in every case before
     the `if (hdr == NULL)` guard (:828). `adev->gfx.mec2_fw` is NULL on
     `num_mec==1` VI parts (gfx_v8_0.c:2029-2041 — TOPAZ/STONEY/default; STONEY is
     upstream-KFD-supported, one probe-list entry away from this tree's list at
     amdgpu_amdkfd.c:65-68), `adev->sdma.instance[1].fw` NULL on single-instance
     parts (sdma_v3_0.c:1114-1118) → NULL-deref panic on enable-day.
   - `get_sdma_base_addr` gfx_v8.c:291-300 / `kgd_hqd_sdma_dump` :486-492:
     MQD/caller-sourced engine_id/queue_id multiplied into MMIO offsets unchecked
     (DF-4499 hazard #1, multiplication flavour).
   - `acquire_queue` :211-220, `kgd_init_interrupts` :272-279, `kgd_hqd_load`
     :331-332: division by `adev->gfx.mec.num_pipe_per_mec` without a zero check.
   - Note-only: `set_scratch_backing_va` :768-776 truncates 64-bit va to 32 bits —
     upstream-identical code, not a DF divergence.

3. **In-bounds confirmations (negative results with line evidence)** — see README.md:
   MQD register walks 0x3245..0x326c / 0x326f..0x3278 ↔ vi_structs.h:289-340 exact
   (max index 51, struct extends to :417); hqd_dump 54+4 exact + WARN_ON_ONCE-guarded;
   get_tile_config ARRAY_SIZE over fixed arrays (amdgpu_gfx.h:175-176);
   invalidate_tlbs loop 0..15 gated; set_vm_context_page_table_base /
   invalidate_tlbs_vmid is_kfd_vmid-gated (vmid 8..15 → +vmid-8 in 0..7).

## Why not reproduced / not falsified on the guest

There is no trigger to run: the code is absent from every build and the guest has no
AMD hardware (env.txt). A PoC would require (a) adding the file to the build,
(b) defining CONFIG_HSA_AMD, (c) porting the KFD frontend, and (d) an AMD gfx8 APU —
none of which exist on this system. The verification deliverable is the reachability
analysis above plus the hardening diff.

## Exploit chain

None — dead code today. On enable-day without the guards: hazards 1-2 give
attacker-influenced OOB MMIO read/write (register-space corruption, GPU lockup /
potential system instability) from whatever privilege the kfd frontend grants its
callers; hazard 3 gives a NULL-deref panic.

## Fix

fix.diff (not applied; authored against read-only sys/): vmid<16 guards in
kgd_set_pasid_vmid_mapping and both ATC mapping getters; per-case firmware pointer
NULL checks before deref; engine/queue bounds in the SDMA MMIO-offset paths.
Recommended one-liner: "when enabling KFD add vmid<16, engine/queue bounds and fw
NULL checks to the gfx8 kfd backend (fix.diff)".

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