From: Victor Skvortsov <victor.skvort...@amd.com>

[ Upstream commit 9e823f307074c0f82b5f6044943b0086e3079bed ]

Register access from userspace should be blocked until
reset is complete.

Signed-off-by: Victor Skvortsov <victor.skvort...@amd.com>
Reviewed-by: Alex Deucher <alexander.deuc...@amd.com>
Signed-off-by: Alex Deucher <alexander.deuc...@amd.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 43 ++++++++++++++++++-------
 1 file changed, 31 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 66782be5917b9..96af9ff1acb67 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -43,6 +43,7 @@
 #include "amdgpu_gem.h"
 #include "amdgpu_display.h"
 #include "amdgpu_ras.h"
+#include "amdgpu_reset.h"
 #include "amd_pcie.h"
 
 void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev)
@@ -778,6 +779,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
                                    ? -EFAULT : 0;
        }
        case AMDGPU_INFO_READ_MMR_REG: {
+               int ret = 0;
                unsigned int n, alloc_size;
                uint32_t *regs;
                unsigned int se_num = (info->read_mmr_reg.instance >>
@@ -787,24 +789,37 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
                                   AMDGPU_INFO_MMR_SH_INDEX_SHIFT) &
                                  AMDGPU_INFO_MMR_SH_INDEX_MASK;
 
+               if (!down_read_trylock(&adev->reset_domain->sem))
+                       return -ENOENT;
+
                /* set full masks if the userspace set all bits
                 * in the bitfields
                 */
-               if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK)
+               if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK) {
                        se_num = 0xffffffff;
-               else if (se_num >= AMDGPU_GFX_MAX_SE)
-                       return -EINVAL;
-               if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK)
+               } else if (se_num >= AMDGPU_GFX_MAX_SE) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK) {
                        sh_num = 0xffffffff;
-               else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE)
-                       return -EINVAL;
+               } else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE) {
+                       ret = -EINVAL;
+                       goto out;
+               }
 
-               if (info->read_mmr_reg.count > 128)
-                       return -EINVAL;
+               if (info->read_mmr_reg.count > 128) {
+                       ret = -EINVAL;
+                       goto out;
+               }
 
                regs = kmalloc_array(info->read_mmr_reg.count, sizeof(*regs), 
GFP_KERNEL);
-               if (!regs)
-                       return -ENOMEM;
+               if (!regs) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
                alloc_size = info->read_mmr_reg.count * sizeof(*regs);
 
                amdgpu_gfx_off_ctrl(adev, false);
@@ -816,13 +831,17 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
                                              info->read_mmr_reg.dword_offset + 
i);
                                kfree(regs);
                                amdgpu_gfx_off_ctrl(adev, true);
-                               return -EFAULT;
+                               ret = -EFAULT;
+                               goto out;
                        }
                }
                amdgpu_gfx_off_ctrl(adev, true);
                n = copy_to_user(out, regs, min(size, alloc_size));
                kfree(regs);
-               return n ? -EFAULT : 0;
+               ret = (n ? -EFAULT : 0);
+out:
+               up_read(&adev->reset_domain->sem);
+               return ret;
        }
        case AMDGPU_INFO_DEV_INFO: {
                struct drm_amdgpu_info_device *dev_info;
-- 
2.43.0

Reply via email to