amdgpu_amdkfd_gfx_v9: entire KFD backend is dead code on DragonFly; latent unvalidated vmid/engine_id index arithmetic should be guarded before KFD is ever enabled
Summary
CONFIG_HSA_AMD is undefined tree-wide, kgd2kfd=NULL, probe early-returns, no /dev/kfd - unreachable today (verified 3 ways). Latent hazards for the enable-day: get_sdma_base_addr indexes stack base[2] with MQD-sourced engine_id unbounded; set_pasid_vmid_mapping computes 1U<<(vmid+16) with no local bound; is_kfd_vmid's (1<<vmid) is UB for vmid>=32 and x86 shift-wrap lets vmid==40 pass the 0xFF00 test, feeding +80-dword offsets into set_vm_context_page_table_base. Add-local-guards fix authored.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4499 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | readme | dead-code proof + latent hazards + in-bounds confirmations | 3.4 KB | β raw |
| VERDICT.md | verdict | verification narrative | 1.9 KB | β raw |
| env.txt | env | guest: no AMD HW / no kfd / no dri | 129 B | view raw |
| fix.diff | hardening-fix | engine_id and vmid guards | 980 B | view raw |
| verdict.json | verdict-json | machine verdict (strict status set) | 2.3 KB | view raw |
DF-4499 β amdgpu_amdkfd_gfx_v9.c is dead code on DragonFly; latent unvalidated index arithmetic for the day KFD is enabled
File: sys/dev/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c (pass 2)
What (dead-code proof)
The Vega10/Vega20/Raven KFD backend compiled into the amdgpu KLD is unreachable on DragonFly:
CONFIG_HSA_AMDis defined nowhere in the tree (no#define, no-DCONFIG_HSA_AMDinsys/dev/drm/amd/amdgpu/MakefileKCFLAGS).- Therefore
amdgpu_amdkfd_init()takes the#elsebranch:kgd2kfd = NULL(amdgpu_amdkfd.c:33-50). amdgpu_amdkfd_device_probe()returns atif (!kgd2kfd) return;before ever callingamdgpu_amdkfd_gfx_9_0_get_functions()(amdgpu_amdkfd.c:59-71) β soadev->kfdstays NULL.- There is no KFD frontend in the tree (no
sys/dev/drm/amd/amdkfd/, no/dev/kfd): nothing consumes thekfd2kgdtable (amdgpu_amdkfd_gfx_v9.c:169-225). amdgpu_amdkfd_is_kfd_vmid()(amdgpu_amdkfd.c:514-523) gates every vmid-taking entry of this file onadev->kfdβ always NULL here β always false βinvalidate_tlbs_vmid()/set_vm_context_page_table_base()are no-ops even if reached.
Guest evidence: no AMD (0x1002) PCI devices, no /dev/dri, no /dev/kfd
(env.txt).
Latent hazards (audit of the exported functions for the day it is enabled)
get_sdma_base_addr()(amdgpu_amdkfd_gfx_v9.c:372-390): indexes stack arrayuint32_t base[2]withengine_idtaken from the MQD (m->sdma_engine_id) with no local bound;queue_idlikewise scales the register stride unbounded. Validation currently lives only in the absent KFD frontend.kgd_set_pasid_vmid_mapping()(:291-346):1U << (vmid + 16)and register+ vmidoffsets rely entirely on the caller keepingvmid <= 15; a vmid β₯ 16 is silent UB / arbitrary adjacent MMIO writes.amdgpu_amdkfd_is_kfd_vmid()(amdgpu_amdkfd.c:514):(1 << vmid)is UB forvmid >= 32; on x86 the shift wraps mod 32, so e.g. vmid=40 passes the0xFF00bitmap test and would feedvmid*2(80 dwords) offsets intoset_vm_context_page_table_base()(:1015-1052).- Unbounded
cpu_relax()MMIO ACK polls inkgd_set_pasid_vmid_mapping()(:315-319,:332-336) andwrite_vmid_invalidate_request()(:830-837): a hung GPU wedges the calling kernel thread forever (same shape as upstream Linux; noted for completeness).
Verified in-bounds during this audit (negative results with weight)
kgd_hqd_load()MQDβHQD register walk (:432-437): reads exactly the contiguousuint32_tspancp_mqd_base_addr_lo β¦ cp_hqd_pq_wptr_hi(v9_structs.h:289-344), 56 dwords β matchesHQD_N_REGS 56.kgd_hqd_dump()/kgd_hqd_sdma_dump()(:497-531,:603-631): allocations sized to the walked ranges (56 and 42 pairs) andDUMP_REGbounds-checked withWARN_ON_ONCE.amdgpu_amdkfd_get_tile_config()(:151-167):ARRAY_SIZEover genuine fixed-size arrays (tile_mode_array[32],macrotile_mode_array[16],amdgpu_gfx.h).invalidate_tlbs()vmid loop is0..15withis_kfd_vmid+ pasid match (:882-892).get_fw_version()NULL-checks every firmware pointer before dereference (:1008-1009).
Fix
fix.diff: add explicit engine_id < 2 / vmid < 16 guards at the two
latent index-arithmetic sites in this file. Info severity β defense-in-depth
for a backend that is currently unreachable.
VERDICT DF-4499 β gfx_v9 KFD backend dead on DF; latent index-arithmetic hazards
Bottom line
Info finding; PoC execution skipped (not applicable β the finding IS the unreachability). Verified at source and guest level:
CONFIG_HSA_AMDundefined tree-wide βkgd2kfd = NULL(amdgpu_amdkfd.c:33-50) βamdgpu_amdkfd_device_probe()early-returns (:59-71) βadev->kfdNULL βamdgpu_amdkfd_is_kfd_vmid()always false (:514-523) β everykfd2kgdentry exported byamdgpu_amdkfd_gfx_v9.c:169-225is unreachable, and no KFD frontend (amd/amdkfd/,/dev/kfd) exists in the tree to call them anyway.- Guest: no 0x1002 PCI devices, no
/dev/dri, no/dev/kfd, no drm KLDs (env.txt).
Audit result for the exported functions (for the day KFD is enabled)
Confirmed in-bounds: hqd_load MQD walk (56 dwords, v9_structs.h:289-344),
hqd_dump/sdma_dump allocations+guards, tile_config ARRAY_SIZE over real
arrays, TLB vmid loop 0..15, fw_version NULL checks.
Latent hazards (unreachable today, fix when enabling):
1. get_sdma_base_addr base[engine_id] OOB for engine_id > 1 (MQD-sourced).
2. kgd_set_pasid_vmid_mapping 1U << (vmid+16) / +vmid register walks
with no local vmid bound.
3. is_kfd_vmid (1 << vmid) UB at vmid β₯ 32 (x86 shift-wrap can pass the
0xFF00 test for vmid β‘ 8..15 mod 32 β vmid*2 offsets up to +80 dwords in
set_vm_context_page_table_base).
4. Unbounded cpu_relax() ACK polls (GPU hang β kernel thread hang).
fix.diff adds explicit engine_id < 2 and vmid < 16 guards in this file.
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.
Fix verification
not_testablefix.diff authored against read-only sys/ as hardening for currently dead code; no runtime validation applicable
fix.diff
Confirmed kernel references
- sys/dev/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c:169-225
- sys/dev/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c:291-346
- sys/dev/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c:372-390
- sys/dev/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c:830-837
- sys/dev/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c:1015-1052
- sys/dev/drm/amd/amdgpu/amdgpu_amdkfd.c:33-50
- sys/dev/drm/amd/amdgpu/amdgpu_amdkfd.c:59-71
- sys/dev/drm/amd/amdgpu/amdgpu_amdkfd.c:514-523
Detail
Evidence (decisive lines)
env.txt (guest: no 0x1002 devices, /dev/dri and /dev/kfd absent); amdgpu_amdkfd.c:33-50,59-71,514-523 (dead-code chain); VERDICT.md (in-bounds confirmations + latent hazards)
PoC changes
not applicable (no trigger; verification = dead-code proof + guest device-absence evidence)
Verified recommended fix
when enabling KFD: add engine_id<2 and vmid<16 guards (fix.diff) and fix the (1<<vmid) shift UB in amdgpu_amdkfd_is_kfd_vmid
Verdict
Info finding verified by source and guest inspection: the entire kfd2kgd backend of amdgpu_amdkfd_gfx_v9.c is dead code on DragonFly (CONFIG_HSA_AMD undefined tree-wide forces kgd2kfd=NULL, probe early-returns, adev->kfd NULL, and no amd/amdkfd frontend or /dev/kfd exists). No PoC is applicable - the unreachability itself is the verified fact; guest confirms no AMD PCI devices, no /dev/dri, no /dev/kfd, no drm KLDs. Latent hazards for the day KFD is enabled are documented and guarded by fix.diff.
No comments yet.