]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amd/pm: Disable MMIO access during SMU Mode 1 reset
authorPerry Yuan <perry.yuan@amd.com>
Thu, 25 Dec 2025 08:43:49 +0000 (16:43 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 7 Jan 2026 22:24:10 +0000 (17:24 -0500)
During Mode 1 reset, the ASIC undergoes a reset cycle and becomes
temporarily inaccessible via PCIe. Any attempt to access MMIO registers
during this window (e.g., from interrupt handlers or other driver threads)
can result in uncompleted PCIe transactions, leading to NMI panics or
system hangs.

To prevent this, set the `no_hw_access` flag to true immediately after
triggering the reset. This signals other driver components to skip
register accesses while the device is offline.

A memory barrier `smp_mb()` is added to ensure the flag update is
globally visible to all cores before the driver enters the sleep/wait
state.

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 7edb503fe4b6d67f47d8bb0dfafb8e699bb0f8a4)

drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c

index 12201b8e99b3fc71815640ae93e01451f859f6ed..25f49be4d0bd4aaf97d9ccc809c62b8fa0c56460 100644 (file)
@@ -5867,6 +5867,9 @@ int amdgpu_device_mode1_reset(struct amdgpu_device *adev)
        if (ret)
                goto mode1_reset_failed;
 
+       /* enable mmio access after mode 1 reset completed */
+       adev->no_hw_access = false;
+
        amdgpu_device_load_pci_state(adev->pdev);
        ret = amdgpu_psp_wait_for_bootloader(adev);
        if (ret)
index 677781060246f96584e8b4de5605ceeab079dc39..eaeff6a9bc50fc254ed57e1f752aceb55d5b4911 100644 (file)
@@ -2923,8 +2923,13 @@ static int smu_v13_0_0_mode1_reset(struct smu_context *smu)
                break;
        }
 
-       if (!ret)
+       if (!ret) {
+               /* disable mmio access while doing mode 1 reset*/
+               smu->adev->no_hw_access = true;
+               /* ensure no_hw_access is globally visible before any MMIO */
+               smp_mb();
                msleep(SMU13_MODE1_RESET_WAIT_TIME_IN_MS);
+       }
 
        return ret;
 }
index 2cea688c604f27754f9fc23cce16a17f93064400..33c3cd2e1e244a1a62ab5fc75a1d1d33442545c8 100644 (file)
@@ -2143,10 +2143,15 @@ static int smu_v14_0_2_mode1_reset(struct smu_context *smu)
 
        ret = smu_cmn_send_debug_smc_msg(smu, DEBUGSMC_MSG_Mode1Reset);
        if (!ret) {
-               if (amdgpu_emu_mode == 1)
+               if (amdgpu_emu_mode == 1) {
                        msleep(50000);
-               else
+               } else {
+                       /* disable mmio access while doing mode 1 reset*/
+                       smu->adev->no_hw_access = true;
+                       /* ensure no_hw_access is globally visible before any MMIO */
+                       smp_mb();
                        msleep(1000);
+               }
        }
 
        return ret;