The MES event-log/MSCRATCH region is only zeroed once at sw_init. On the
resume path (hw_init without sw_init) it retains stale data, so with
mes_log_enable=1 the MES firmware walks stale pointers on activation and
triggers a recoverable CPC page fault:

  [gfxhub] page fault (src_id:0 ring:153 vmid:0 pasid:0)
    in page starting at address 0x000000855c237000 from client 10
    GCVM_L2_PROTECTION_FAULT_STATUS:0x00000B33
    Faulty UTCL2 client ID: CPC (0x5)
    MORE_FAULTS: 0x1  WALKER_ERROR: 0x1  PERMISSION_FAULTS: 0x3
    MAPPING_ERROR: 0x1  RW: 0x0

Re-clear it before unhalting MES.

Signed-off-by: Jesse Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c 
b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
index ee72afdb0a1d..9e149cf98889 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
@@ -1306,6 +1306,17 @@ static void mes_v12_0_enable(struct amdgpu_device *adev, 
bool enable)
        uint32_t pipe, data = 0;
 
        if (enable) {
+               /*
+                * The event-log/MSCRATCH region is only zeroed once at sw_init.
+                * On the resume path (hw_init without sw_init) it still holds 
the
+                * previous session's data, so the MES firmware walks stale
+                * pointers on activation and triggers a CPC page fault. 
Re-clear
+                * it before unhalting MES.
+                */
+               if (amdgpu_mes_log_enable && adev->mes.event_log_cpu_addr)
+                       memset(adev->mes.event_log_cpu_addr, 0,
+                              adev->mes.event_log_size);
+
                mutex_lock(&adev->srbm_mutex);
                for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) {
                        soc24_grbm_select(adev, 3, pipe, 0, 0);
-- 
2.45.1

Reply via email to