gfx_v12_0_update_spm_vmid() does a read-modify-write of RLC_SPM_MC_CNTL
over MMIO without keeping GFX powered, unlike gfx11. When GFX is in
GFXOFF at that point the update doesn't stick, and with the SPM VMID
programmed on submission again, the job of a process with a reserved
VMID can still run with the SPM writing through VMID 0.

On navi48, after a few other submissions and a VM fault on the same VM,
a COPY_DATA of RLC_SPM_MC_CNTL from such a job reads 0 although the
update was called for it:

  $ run testcase: 
cs-secure-ib-compute,gem-mapping-info-high-va,reserved-vmid-spm-vmid
  amdgpu 0000:03:00.0: [gfxhub] page fault (src_id:0 ring:40 vmid:7 pasid:185)
  amdgpu 0000:03:00.0:   Faulty UTCL2 client ID: SDMA1 (0xe)
  RLC_SPM_MC_CNTL in the job: 0x00000000

With GFXOFF disallowed around the update it reads the reserved VMID 15.

Fixes: 52cb80c12e8a ("drm/amdgpu: Add gfx v12_0 ip block support (v6)")
Signed-off-by: Jesse Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index d334fb805020..9bdd82cc202d 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -3963,6 +3963,7 @@ static void gfx_v12_0_update_spm_vmid(struct 
amdgpu_device *adev,
 {
        u32 reg, data;
 
+       amdgpu_gfx_off_ctrl(adev, false);
        reg = SOC15_REG_OFFSET(GC, 0, regRLC_SPM_MC_CNTL);
        if (amdgpu_sriov_is_pp_one_vf(adev))
                data = RREG32_NO_KIQ(reg);
@@ -3976,6 +3977,7 @@ static void gfx_v12_0_update_spm_vmid(struct 
amdgpu_device *adev,
                WREG32_SOC15_NO_KIQ(GC, 0, regRLC_SPM_MC_CNTL, data);
        else
                WREG32_SOC15(GC, 0, regRLC_SPM_MC_CNTL, data);
+       amdgpu_gfx_off_ctrl(adev, true);
 }
 
 static const struct amdgpu_rlc_funcs gfx_v12_0_rlc_funcs = {
-- 
2.50.1

Reply via email to