mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2026-01-27 12:47:24 +01:00
drm/amdgpu: Use vmemdup_array_user in amdgpu_bo_create_list_entry_array
Replace kvmalloc_array() + copy_from_user() with vmemdup_array_user() on the fast path. This shrinks the source code and improves separation between the kernel and userspace slabs. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
6530748485
commit
c4ac100e9a
|
|
@ -184,43 +184,36 @@ void amdgpu_bo_list_put(struct amdgpu_bo_list *list)
|
|||
int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
|
||||
struct drm_amdgpu_bo_list_entry **info_param)
|
||||
{
|
||||
const void __user *uptr = u64_to_user_ptr(in->bo_info_ptr);
|
||||
const uint32_t info_size = sizeof(struct drm_amdgpu_bo_list_entry);
|
||||
const void __user *uptr = u64_to_user_ptr(in->bo_info_ptr);
|
||||
const uint32_t bo_info_size = in->bo_info_size;
|
||||
const uint32_t bo_number = in->bo_number;
|
||||
struct drm_amdgpu_bo_list_entry *info;
|
||||
int r;
|
||||
|
||||
info = kvmalloc_array(in->bo_number, info_size, GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
/* copy the handle array from userspace to a kernel buffer */
|
||||
r = -EFAULT;
|
||||
if (likely(info_size == in->bo_info_size)) {
|
||||
unsigned long bytes = in->bo_number *
|
||||
in->bo_info_size;
|
||||
|
||||
if (copy_from_user(info, uptr, bytes))
|
||||
goto error_free;
|
||||
|
||||
if (likely(info_size == bo_info_size)) {
|
||||
info = vmemdup_array_user(uptr, bo_number, info_size);
|
||||
if (IS_ERR(info))
|
||||
return PTR_ERR(info);
|
||||
} else {
|
||||
unsigned long bytes = min(in->bo_info_size, info_size);
|
||||
const uint32_t bytes = min(bo_info_size, info_size);
|
||||
unsigned i;
|
||||
|
||||
memset(info, 0, in->bo_number * info_size);
|
||||
for (i = 0; i < in->bo_number; ++i) {
|
||||
if (copy_from_user(&info[i], uptr, bytes))
|
||||
goto error_free;
|
||||
info = kvmalloc_array(bo_number, info_size, GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
uptr += in->bo_info_size;
|
||||
memset(info, 0, bo_number * info_size);
|
||||
for (i = 0; i < bo_number; ++i, uptr += bo_info_size) {
|
||||
if (copy_from_user(&info[i], uptr, bytes)) {
|
||||
kvfree(info);
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*info_param = info;
|
||||
return 0;
|
||||
|
||||
error_free:
|
||||
kvfree(info);
|
||||
return r;
|
||||
}
|
||||
|
||||
int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user