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 (v)memdup_array_user in amdgpu_cs_pass1

Replace k(v)malloc_array() + copy_from_user() with (v)memdup_array_user().

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
d4b6274c dea75df7

+10 -23
+10 -23
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
··· 178 178 struct amdgpu_fpriv *fpriv = p->filp->driver_priv; 179 179 unsigned int num_ibs[AMDGPU_CS_GANG_SIZE] = { }; 180 180 struct amdgpu_vm *vm = &fpriv->vm; 181 - uint64_t *chunk_array_user; 182 181 uint64_t *chunk_array; 183 182 uint32_t uf_offset = 0; 184 183 size_t size; 185 184 int ret; 186 185 int i; 187 186 188 - chunk_array = kvmalloc_array(cs->in.num_chunks, sizeof(uint64_t), 189 - GFP_KERNEL); 190 - if (!chunk_array) 191 - return -ENOMEM; 192 - 193 - /* get chunks */ 194 - chunk_array_user = u64_to_user_ptr(cs->in.chunks); 195 - if (copy_from_user(chunk_array, chunk_array_user, 196 - sizeof(uint64_t)*cs->in.num_chunks)) { 197 - ret = -EFAULT; 198 - goto free_chunk; 199 - } 187 + chunk_array = memdup_array_user(u64_to_user_ptr(cs->in.chunks), 188 + cs->in.num_chunks, 189 + sizeof(uint64_t)); 190 + if (IS_ERR(chunk_array)) 191 + return PTR_ERR(chunk_array); 200 192 201 193 p->nchunks = cs->in.num_chunks; 202 194 p->chunks = kvmalloc_array(p->nchunks, sizeof(struct amdgpu_cs_chunk), ··· 201 209 for (i = 0; i < p->nchunks; i++) { 202 210 struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL; 203 211 struct drm_amdgpu_cs_chunk user_chunk; 204 - uint32_t __user *cdata; 205 212 206 213 chunk_ptr = u64_to_user_ptr(chunk_array[i]); 207 214 if (copy_from_user(&user_chunk, chunk_ptr, ··· 213 222 p->chunks[i].length_dw = user_chunk.length_dw; 214 223 215 224 size = p->chunks[i].length_dw; 216 - cdata = u64_to_user_ptr(user_chunk.chunk_data); 217 225 218 - p->chunks[i].kdata = kvmalloc_array(size, sizeof(uint32_t), 219 - GFP_KERNEL); 220 - if (p->chunks[i].kdata == NULL) { 221 - ret = -ENOMEM; 226 + p->chunks[i].kdata = vmemdup_array_user(u64_to_user_ptr(user_chunk.chunk_data), 227 + size, 228 + sizeof(uint32_t)); 229 + if (IS_ERR(p->chunks[i].kdata)) { 230 + ret = PTR_ERR(p->chunks[i].kdata); 222 231 i--; 223 232 goto free_partial_kdata; 224 233 } 225 234 size *= sizeof(uint32_t); 226 - if (copy_from_user(p->chunks[i].kdata, cdata, size)) { 227 - ret = -EFAULT; 228 - goto free_partial_kdata; 229 - } 230 235 231 236 /* Assume the worst on the following checks */ 232 237 ret = -EINVAL;