Commit d4b6274c authored by Tvrtko Ursulin's avatar Tvrtko Ursulin Committed by Alex Deucher
Browse files

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: default avatarTvrtko Ursulin <tvrtko.ursulin@igalia.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent dea75df7
Loading
Loading
Loading
Loading
+10 −23
Original line number Diff line number Diff line
@@ -178,25 +178,17 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
	struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
	unsigned int num_ibs[AMDGPU_CS_GANG_SIZE] = { };
	struct amdgpu_vm *vm = &fpriv->vm;
	uint64_t *chunk_array_user;
	uint64_t *chunk_array;
	uint32_t uf_offset = 0;
	size_t size;
	int ret;
	int i;

	chunk_array = kvmalloc_array(cs->in.num_chunks, sizeof(uint64_t),
				     GFP_KERNEL);
	if (!chunk_array)
		return -ENOMEM;

	/* get chunks */
	chunk_array_user = u64_to_user_ptr(cs->in.chunks);
	if (copy_from_user(chunk_array, chunk_array_user,
			   sizeof(uint64_t)*cs->in.num_chunks)) {
		ret = -EFAULT;
		goto free_chunk;
	}
	chunk_array = memdup_array_user(u64_to_user_ptr(cs->in.chunks),
					cs->in.num_chunks,
					sizeof(uint64_t));
	if (IS_ERR(chunk_array))
		return PTR_ERR(chunk_array);

	p->nchunks = cs->in.num_chunks;
	p->chunks = kvmalloc_array(p->nchunks, sizeof(struct amdgpu_cs_chunk),
@@ -209,7 +201,6 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
	for (i = 0; i < p->nchunks; i++) {
		struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL;
		struct drm_amdgpu_cs_chunk user_chunk;
		uint32_t __user *cdata;

		chunk_ptr = u64_to_user_ptr(chunk_array[i]);
		if (copy_from_user(&user_chunk, chunk_ptr,
@@ -222,20 +213,16 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
		p->chunks[i].length_dw = user_chunk.length_dw;

		size = p->chunks[i].length_dw;
		cdata = u64_to_user_ptr(user_chunk.chunk_data);

		p->chunks[i].kdata = kvmalloc_array(size, sizeof(uint32_t),
						    GFP_KERNEL);
		if (p->chunks[i].kdata == NULL) {
			ret = -ENOMEM;
		p->chunks[i].kdata = vmemdup_array_user(u64_to_user_ptr(user_chunk.chunk_data),
							size,
							sizeof(uint32_t));
		if (IS_ERR(p->chunks[i].kdata)) {
			ret = PTR_ERR(p->chunks[i].kdata);
			i--;
			goto free_partial_kdata;
		}
		size *= sizeof(uint32_t);
		if (copy_from_user(p->chunks[i].kdata, cdata, size)) {
			ret = -EFAULT;
			goto free_partial_kdata;
		}

		/* Assume the worst on the following checks */
		ret = -EINVAL;