Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Tvrtko Ursulin and committed by
Alex Deucher
c4ac100e 65307484

+17 -24
+17 -24
drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
··· 184 184 int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in, 185 185 struct drm_amdgpu_bo_list_entry **info_param) 186 186 { 187 - const void __user *uptr = u64_to_user_ptr(in->bo_info_ptr); 188 187 const uint32_t info_size = sizeof(struct drm_amdgpu_bo_list_entry); 188 + const void __user *uptr = u64_to_user_ptr(in->bo_info_ptr); 189 + const uint32_t bo_info_size = in->bo_info_size; 190 + const uint32_t bo_number = in->bo_number; 189 191 struct drm_amdgpu_bo_list_entry *info; 190 - int r; 191 - 192 - info = kvmalloc_array(in->bo_number, info_size, GFP_KERNEL); 193 - if (!info) 194 - return -ENOMEM; 195 192 196 193 /* copy the handle array from userspace to a kernel buffer */ 197 - r = -EFAULT; 198 - if (likely(info_size == in->bo_info_size)) { 199 - unsigned long bytes = in->bo_number * 200 - in->bo_info_size; 201 - 202 - if (copy_from_user(info, uptr, bytes)) 203 - goto error_free; 204 - 194 + if (likely(info_size == bo_info_size)) { 195 + info = vmemdup_array_user(uptr, bo_number, info_size); 196 + if (IS_ERR(info)) 197 + return PTR_ERR(info); 205 198 } else { 206 - unsigned long bytes = min(in->bo_info_size, info_size); 199 + const uint32_t bytes = min(bo_info_size, info_size); 207 200 unsigned i; 208 201 209 - memset(info, 0, in->bo_number * info_size); 210 - for (i = 0; i < in->bo_number; ++i) { 211 - if (copy_from_user(&info[i], uptr, bytes)) 212 - goto error_free; 202 + info = kvmalloc_array(bo_number, info_size, GFP_KERNEL); 203 + if (!info) 204 + return -ENOMEM; 213 205 214 - uptr += in->bo_info_size; 206 + memset(info, 0, bo_number * info_size); 207 + for (i = 0; i < bo_number; ++i, uptr += bo_info_size) { 208 + if (copy_from_user(&info[i], uptr, bytes)) { 209 + kvfree(info); 210 + return -EFAULT; 211 + } 215 212 } 216 213 } 217 214 218 215 *info_param = info; 219 216 return 0; 220 - 221 - error_free: 222 - kvfree(info); 223 - return r; 224 217 } 225 218 226 219 int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,