drm/amdgpu/psp: add a mutex to protect access to the psp ring
authorAlex Deucher <alexander.deucher@amd.com>
Mon, 8 Jul 2019 18:33:22 +0000 (13:33 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 9 Jul 2019 22:43:39 +0000 (17:43 -0500)
We need to serialize access to the psp ring if there are multiple
callers at runtime.

Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h

index 7401bc95c15be39b0e797394114d282371e9d68b..5a7f893cf72448d9a4d6e9c12b0d3827d3e7bdcb 100644 (file)
@@ -2537,6 +2537,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        hash_init(adev->mn_hash);
        mutex_init(&adev->lock_reset);
        mutex_init(&adev->virt.dpm_mutex);
+       mutex_init(&adev->psp.mutex);
 
        r = amdgpu_device_check_arguments(adev);
        if (r)
index e69ad6e089c5b7b6dc0878a7ff8d0a504418a934..9882d90e765ef57c9654cdb0000b40623707b024 100644 (file)
@@ -130,6 +130,8 @@ psp_cmd_submit_buf(struct psp_context *psp,
        int index;
        int timeout = 2000;
 
+       mutex_lock(&psp->mutex);
+
        memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE);
 
        memcpy(psp->cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp));
@@ -139,6 +141,7 @@ psp_cmd_submit_buf(struct psp_context *psp,
                             fence_mc_addr, index);
        if (ret) {
                atomic_dec(&psp->fence_value);
+               mutex_unlock(&psp->mutex);
                return ret;
        }
 
@@ -161,8 +164,10 @@ psp_cmd_submit_buf(struct psp_context *psp,
                                  ucode->ucode_id);
                DRM_WARN("psp command failed and response status is (%d)\n",
                          psp->cmd_buf_mem->resp.status);
-               if (!timeout)
+               if (!timeout) {
+                       mutex_unlock(&psp->mutex);
                        return -EINVAL;
+               }
        }
 
        /* get xGMI session id from response buffer */
@@ -172,6 +177,7 @@ psp_cmd_submit_buf(struct psp_context *psp,
                ucode->tmr_mc_addr_lo = psp->cmd_buf_mem->resp.fw_addr_lo;
                ucode->tmr_mc_addr_hi = psp->cmd_buf_mem->resp.fw_addr_hi;
        }
+       mutex_unlock(&psp->mutex);
 
        return ret;
 }
@@ -1188,10 +1194,16 @@ failed:
 
 int psp_gpu_reset(struct amdgpu_device *adev)
 {
+       int ret;
+
        if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
                return 0;
 
-       return psp_mode1_reset(&adev->psp);
+       mutex_lock(&adev->psp.mutex);
+       ret = psp_mode1_reset(&adev->psp);
+       mutex_unlock(&adev->psp.mutex);
+
+       return ret;
 }
 
 int psp_rlc_autoload_start(struct psp_context *psp)
index 6039acc84346956553d54d14b901c862260306ed..e28cf5e4016ea629909550b4983cd5b74d930938 100644 (file)
@@ -201,6 +201,7 @@ struct psp_context
        uint8_t                         *ta_ras_start_addr;
        struct psp_xgmi_context         xgmi_context;
        struct psp_ras_context          ras;
+       struct mutex                    mutex;
 };
 
 struct amdgpu_psp_funcs {