Commit 9e823f30 authored by Victor Skvortsov's avatar Victor Skvortsov Committed by Alex Deucher

drm/amdgpu: Block MMR_READ IOCTL in reset

Register access from userspace should be blocked until
reset is complete.
Signed-off-by: default avatarVictor Skvortsov <victor.skvortsov@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a85c3db6
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "amdgpu_gem.h" #include "amdgpu_gem.h"
#include "amdgpu_display.h" #include "amdgpu_display.h"
#include "amdgpu_ras.h" #include "amdgpu_ras.h"
#include "amdgpu_reset.h"
#include "amd_pcie.h" #include "amd_pcie.h"
void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev) 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) ...@@ -778,6 +779,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
? -EFAULT : 0; ? -EFAULT : 0;
} }
case AMDGPU_INFO_READ_MMR_REG: { case AMDGPU_INFO_READ_MMR_REG: {
int ret = 0;
unsigned int n, alloc_size; unsigned int n, alloc_size;
uint32_t *regs; uint32_t *regs;
unsigned int se_num = (info->read_mmr_reg.instance >> 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) ...@@ -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_SHIFT) &
AMDGPU_INFO_MMR_SH_INDEX_MASK; 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 /* set full masks if the userspace set all bits
* in the bitfields * in the bitfields
*/ */
if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK) if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK) {
se_num = 0xffffffff; se_num = 0xffffffff;
else if (se_num >= AMDGPU_GFX_MAX_SE) } else if (se_num >= AMDGPU_GFX_MAX_SE) {
return -EINVAL; ret = -EINVAL;
if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK) goto out;
}
if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK) {
sh_num = 0xffffffff; sh_num = 0xffffffff;
else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE) } else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE) {
return -EINVAL; ret = -EINVAL;
goto out;
}
if (info->read_mmr_reg.count > 128) if (info->read_mmr_reg.count > 128) {
return -EINVAL; ret = -EINVAL;
goto out;
}
regs = kmalloc_array(info->read_mmr_reg.count, sizeof(*regs), GFP_KERNEL); regs = kmalloc_array(info->read_mmr_reg.count, sizeof(*regs), GFP_KERNEL);
if (!regs) if (!regs) {
return -ENOMEM; ret = -ENOMEM;
goto out;
}
alloc_size = info->read_mmr_reg.count * sizeof(*regs); alloc_size = info->read_mmr_reg.count * sizeof(*regs);
amdgpu_gfx_off_ctrl(adev, false); amdgpu_gfx_off_ctrl(adev, false);
...@@ -816,13 +831,17 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) ...@@ -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); info->read_mmr_reg.dword_offset + i);
kfree(regs); kfree(regs);
amdgpu_gfx_off_ctrl(adev, true); amdgpu_gfx_off_ctrl(adev, true);
return -EFAULT; ret = -EFAULT;
goto out;
} }
} }
amdgpu_gfx_off_ctrl(adev, true); amdgpu_gfx_off_ctrl(adev, true);
n = copy_to_user(out, regs, min(size, alloc_size)); n = copy_to_user(out, regs, min(size, alloc_size));
kfree(regs); kfree(regs);
return n ? -EFAULT : 0; ret = (n ? -EFAULT : 0);
out:
up_read(&adev->reset_domain->sem);
return ret;
} }
case AMDGPU_INFO_DEV_INFO: { case AMDGPU_INFO_DEV_INFO: {
struct drm_amdgpu_info_device *dev_info; struct drm_amdgpu_info_device *dev_info;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment