Avoid kernel panic if MES init fails during driver load. The KIQ ring is
falsely marked as ready as ASICs that use MES, KIQ is owned by MES.

BUG: kernel NULL pointer dereference, address: 0000000000000000
RIP: 0010:gfx_v12_1_wait_reg_mem+0x5a/0x1f0 [amdgpu]
Call Trace:
 gfx_v12_1_ring_emit_reg_write_reg_wait+0x1f/0x30 [amdgpu]
 amdgpu_gmc_fw_reg_write_reg_wait+0xb2/0x190 [amdgpu]
 amdgpu_gmc_flush_gpu_tlb+0x1cc/0x230 [amdgpu]
 amdgpu_gart_invalidate_tlb+0x81/0xa0 [amdgpu]
 amdgpu_gart_unbind+0x72/0x90 [amdgpu]
 amdgpu_ttm_backend_unbind+0xa4/0xb0 [amdgpu]
 amdgpu_ttm_tt_unpopulate+0x13/0xd0 [amdgpu]
 amdttm_tt_unpopulate+0x29/0x70 [amdttm]
 ttm_bo_put+0x1eb/0x360 [amdttm]
 amdgpu_bo_free_kernel+0xf9/0x1f0 [amdgpu]
 amdgpu_ih_ring_fini+0x5a/0x90 [amdgpu]
 amdgpu_irq_fini_hw+0x58/0x80 [amdgpu]
 amdgpu_device_fini_hw+0x4e0/0x5b0 [amdgpu]
 amdgpu_driver_load_kms+0x60/0xa0 [amdgpu]
 amdgpu_pci_probe+0x28e/0x6d0 [amdgpu]
 pci_device_probe+0x19f/0x220
 really_probe+0x1ed/0x340
 driver_probe_device+0x1e/0x80
 __driver_attach+0xd3/0x1a0
 bus_for_each_dev+0x68/0xa0
 bus_add_driver+0x19f/0x270
 driver_register+0x5d/0xf0
 do_one_initcall+0xac/0x200
 do_init_module+0x1ec/0x280
 __se_sys_finit_module+0x2de/0x310
 do_syscall_64+0x6a/0x250
 entry_SYSCALL_64_after_hwframe+0x4b/0x53

Signed-off-by: Harish Kasiviswanathan <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 13 +++++++++++--
 drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c | 13 +++++++++++--
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index cd6c1b6f8894..c765af54669c 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -3524,10 +3524,19 @@ static int gfx_v12_0_cp_resume(struct amdgpu_device 
*adev)
                gfx_v12_0_cp_gfx_enable(adev, true);
        }
 
-       if (adev->enable_mes_kiq && adev->mes.kiq_hw_init)
+       if (adev->enable_mes_kiq && adev->mes.kiq_hw_init) {
                r = amdgpu_mes_kiq_hw_init(adev, 0);
-       else
+               /*
+                * With MES, GFX KIQ ring is owned by the MES and is never
+                * initialized/used directly by the driver, so it must
+                * not be left flagged as ready. mes_v12_0_hw_init() clears
+                * but clear here if MES init fails
+               */
+               if (r)
+                       adev->gfx.kiq[0].ring.sched.ready = false;
+       } else {
                r = gfx_v12_0_kiq_resume(adev);
+       }
        if (r)
                return r;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
index aaa8f4212a15..e87f1baf5cb6 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
@@ -2549,10 +2549,19 @@ static int gfx_v12_1_xcc_cp_resume(struct amdgpu_device 
*adev, uint16_t xcc_mask
 
                gfx_v12_1_xcc_cp_compute_enable(adev, true, xcc_id);
 
-               if (adev->enable_mes_kiq && adev->mes.kiq_hw_init)
+               if (adev->enable_mes_kiq && adev->mes.kiq_hw_init) {
                        r = amdgpu_mes_kiq_hw_init(adev, xcc_id);
-               else
+                       /*
+                        * With MES, GFX KIQ ring is owned by the MES and is 
never
+                        * initialized/used directly by the driver, so it must
+                        * not be left flagged as ready. mes_v12_0_hw_init() 
clears
+                        * but clear here if MES init fails
+                        */
+                       if (r)
+                               adev->gfx.kiq[xcc_id].ring.sched.ready = false;
+               } else {
                        r = gfx_v12_1_xcc_kiq_resume(adev, xcc_id);
+               }
                if (r)
                        return r;
 
-- 
2.43.0

Reply via email to