drm/amdgpu: Fix MMIO access page fault
authorAndrey Grodzovsky <andrey.grodzovsky@amd.com>
Thu, 16 Sep 2021 16:54:07 +0000 (12:54 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 Nov 2021 13:03:54 +0000 (14:03 +0100)
[ Upstream commit c03509cbc01559549700e14c4a6239f2572ab4ba ]

Add more guards to MMIO access post device
unbind/unplug

Bug: https://bugs.archlinux.org/task/72092?project=1&order=dateopened&sort=desc&pagenum=1
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
Reviewed-by: James Zhu <James.Zhu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c

index f493b5c3d382b85df17f0e6d22519b7cfede69fd..79bcc78f77045176c77d6e6ba1c5a3d2f2b1cfd8 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/firmware.h>
+#include <drm/drm_drv.h>
 
 #include "amdgpu.h"
 #include "amdgpu_vcn.h"
@@ -192,11 +193,14 @@ static int vcn_v2_0_sw_init(void *handle)
  */
 static int vcn_v2_0_sw_fini(void *handle)
 {
-       int r;
+       int r, idx;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared_cpu_addr;
 
-       fw_shared->present_flag_0 = 0;
+       if (drm_dev_enter(&adev->ddev, &idx)) {
+               fw_shared->present_flag_0 = 0;
+               drm_dev_exit(idx);
+       }
 
        amdgpu_virt_free_mm_table(adev);
 
index ce64d4016f903827a5cfa5b35fdb64773057e027..381839d005db9b7f2885f4610f3497d718a90673 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/firmware.h>
+#include <drm/drm_drv.h>
 
 #include "amdgpu.h"
 #include "amdgpu_vcn.h"
@@ -233,17 +234,21 @@ static int vcn_v2_5_sw_init(void *handle)
  */
 static int vcn_v2_5_sw_fini(void *handle)
 {
-       int i, r;
+       int i, r, idx;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        volatile struct amdgpu_fw_shared *fw_shared;
 
-       for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
-               if (adev->vcn.harvest_config & (1 << i))
-                       continue;
-               fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr;
-               fw_shared->present_flag_0 = 0;
+       if (drm_dev_enter(&adev->ddev, &idx)) {
+               for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
+                       if (adev->vcn.harvest_config & (1 << i))
+                               continue;
+                       fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr;
+                       fw_shared->present_flag_0 = 0;
+               }
+               drm_dev_exit(idx);
        }
 
+
        if (amdgpu_sriov_vf(adev))
                amdgpu_virt_free_mm_table(adev);