mmhub_v1_0_init_cache_regs never programs mmVM_L2_CNTL3: BANK_SELECT/L2_CACHE_BIGK_FRAGMENT_SIZE computed into a stale CNTL2-derived local and silently dropped (the v5.2-era WREG32 line is missing from the DF vendor sync)
Summary
After tmp is written to CNTL2, the CNTL3 field macros are applied to that stale value and the result is never stored - mmVM_L2_CNTL3 is neither read nor written anywhere in the function, so the MMHUB L2 TLB geometry stays at hw reset defaults (notably translate_further on Raven2 where BANK_SELECT must be 12). The DF vendor sync dropped the WREG32 line (upstream v5.2 has it; the in-tree gfxhub twin programs its instance). Functional misconfiguration/dead-code trap; no demonstrated isolation breach. RMW+write fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4815 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 932 B | β raw | |
| VERDICT.md | β | 4.2 KB | β raw | |
| env.txt | β | 1.5 KB | view raw | |
| fix.diff | β | 661 B | view raw | |
| evidence/comparison.txt | β | 2.9 KB | view raw | |
| evidence/upstream_v5.2_mmhub_v1_0.c | β | 19.0 KB | view raw |
DF-4815 β mmhub_v1_0_init_cache_regs computes VM_L2_CNTL3 (BANK_SELECT /
L2_CACHE_BIGK_FRAGMENT_SIZE) into a stale CNTL2-derived local and never
writes it: the register is left at reset default on every Vega10/12/20/Raven
GART init; the DF vendor-sync dropped the WREG32_SOC15(MMHUB, 0,
mmVM_L2_CNTL3, tmp); line present in the tree's own v5.2-era source.
Nothing to build/run: the defect is a silently-dropped register write at GPU hardware init; the audit guest has no AMD GPU (see env.txt), and no userspace-observable PoC exists for a register that is never programmed.
REPRODUCE (static, decisive): sysctl-less; simply diff: evidence/comparison.txt # DF vs upstream v4.18 vs upstream v5.2 evidence/upstream_v5.2_mmhub_v1_0.c:185 # the line DF is missing sys/dev/drm/amd/amdgpu/mmhub_v1_0.c:171-184 # dead-code block
FIX: fix.diff (git apply --check clean) restores read+write of CNTL3.
DF-4815 VERDICT β mmhub_v1_0_init_cache_regs never programs mmVM_L2_CNTL3
Bottom line. In mmhub_v1_0_init_cache_regs() (called from
mmhub_v1_0_gart_enable() at every GMC/GART initialization on Vega10/12/20
and Raven), the MMHUB L2-TLB geometry registers VM_L2_CNTL3.BANK_SELECT /
VM_L2_CNTL3.L2_CACHE_BIGK_FRAGMENT_SIZE are computed into a stale local
and never written to hardware: after tmp was last assigned from
mmVM_L2_CNTL2 (line 166) and written (line 169), lines 171-179 apply
VM_L2_CNTL3 field macros to that stale CNTL2 value β and the result is
dropped on the floor, because line 181 overwrites tmp with
mmVM_L2_CNTL4_DEFAULT and the only remaining write is to CNTL4 (line 184).
There is no RREG32/WREG32 of mmVM_L2_CNTL3 anywhere in the function.
Consequences:
1. The intended L2 TLB bank-select / bigk-fragment configuration never lands;
MMHUB L2 runs on hardware reset defaults.
2. On Raven/Raven2 with gmc.translate_further (the 128TB+512GB VM layout
selected in gmc_v9_0.c:943-945), BANK_SELECT must be 12 β it stays at the
default, i.e. the TLB geometry silently disagrees with the programmed
page-table depth/block size (mmhub_v1_0_setup_vmid_config), a functional
misconfiguration of the GPU MMU (VM-fault / hang class).
3. The dead computation is a trap for future edits (garbage CNTL2-derived
base would be used if a write were ever added naively β exactly what
upstream v5.2 shipped: it added the write but kept the missing re-read).
Provenance (why this is a real divergence, verified against tags)
- Upstream v4.18 (AMDGPU import era) has the same missing write (evidence/comparison.txt) β the bug was upstream too, then.
- Upstream v5.2 has
WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL3, tmp);(evidence/upstream_v5.2_mmhub_v1_0.c:185) β fixed upstream between 4.18 and 5.2. - The DF file is otherwise v5.2-vintage:
mmhub_v1_0_setup_vmid_configis byte-identical to v5.2 except one deliberately-backported later line (RETRY_PERMISSION_OR_INVALID_PAGE_FAULT 0, the no-retry XNACK change), and init_gart_aperture/system_aperture (fb_start/fb_end, AGP BAR, Raven2 rev_id>=0x8 workaround, amdgpu_gmc_pd_addr) all match the v5.2-era code. β the DF vendor-sync dropped the singleWREG32_SOC15(... mmVM_L2_CNTL3, tmp);line that its own source vintage carries.
Security assessment (honest)
No attacker-controlled input reaches this path (driver-internal constants at hardware init). The impact ceiling is misconfiguration of the GPU VM's L2 TLB: no demonstrated isolation breach (page tables still enforced), but TLB-geometry mismatch on translate_further parts can produce VM faults / GPU hangs (availability), and on any future part whose reset default differs from the driver's assumption the L2 behaves differently than validated. Filed as Low / hardening-correctness, CWE-561 (dead code) + CWE-754-style improper initialization.
Verification performed
- Guest kernel runtime: NOT possible. The audit guest has no AMD GPU at
all (see env.txt; only QEMU std-VGA).
mmhub_v1_0_gart_enableis executed only during amdgpu GMC init on Vega10-class ASICs. Statusuntested(device absent). Nothing else on the guest exercises this file. - Static verification: decisive. evidence/comparison.txt shows
side-by-side: DF (no CNTL3 write) / upstream v4.18 (no write) / upstream
v5.2 (write present), plus the vintage proof (setup_vmid_config identity).
A grep for
mmVM_L2_CNTL3over the whole DF tree shows the only MMHUB programming site is this function (gfxhub_v1_0.c has its own separate GFX-side CNTL3 handling) β nothing else compensates for the dropped write.
Fix
Read, set, write β restores upstream v5.2 behavior (and adds the re-read
upstream still lacks). See fix.diff; git apply --check passes against
sys/dev/drm/amd/amdgpu/mmhub_v1_0.c.
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 restores the dropped CNTL3 programming (git apply --check clean); no Vega10 hardware in the audit guest, so patched-kernel behavior cannot be exercised
fix.diff; evidence/comparison.txt; gfxhub_v1_0.c:151-161 in-tree twin shows the intended pattern
Confirmed kernel references
Detail
Evidence (decisive lines)
evidence/comparison.txt (DF vs upstream v4.18 vs v5.2 side-by-side + gfxhub twin); fix.diff applies cleanly; env.txt documents guest hardware absence
PoC changes
n/a (no orchestrator seed; pack authored during this run)
Verified recommended fix
Restore read-modify-write of mmVM_L2_CNTL3 in mmhub_v1_0_init_cache_regs (see fix.diff); matches upstream v5.2 plus the re-read upstream still lacks
Verdict
mmhub_v1_0_init_cache_regs() applies VM_L2_CNTL3 field macros to a stale mmVM_L2_CNTL2-derived local and never writes the result; mmVM_L2_CNTL3 is neither read nor written anywhere in the function, so the MMHUB L2 TLB geometry stays at reset default. The DF file is otherwise v5.2-vintage (setup_vmid_config byte-identical except one backported line), and both upstream v5.2 (evidence/upstream_v5.2_mmhub_v1_0.c:185) and the in-tree GFX-hub twin (gfxhub_v1_0.c:151-161) contain the write the DF sync dropped. Upstream v4.18 carried the same omission, so this is an inherited-then-fixed-upstream bug that the DF sync missed.
No comments yet.