diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 81 | 
1 files changed, 56 insertions, 25 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index 467e8fa6cb8b..f8648e169f8b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -404,27 +404,10 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)  		(args->in.flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_MASK) >>  		AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_SHIFT; -	/* Usermode queues are only supported for GFX IP as of now */ -	if (args->in.ip_type != AMDGPU_HW_IP_GFX && -	    args->in.ip_type != AMDGPU_HW_IP_DMA && -	    args->in.ip_type != AMDGPU_HW_IP_COMPUTE) { -		drm_file_err(uq_mgr->file, "Usermode queue doesn't support IP type %u\n", -			     args->in.ip_type); -		return -EINVAL; -	} -  	r = amdgpu_userq_priority_permit(filp, priority);  	if (r)  		return r; -	if ((args->in.flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE) && -	    (args->in.ip_type != AMDGPU_HW_IP_GFX) && -	    (args->in.ip_type != AMDGPU_HW_IP_COMPUTE) && -	    !amdgpu_is_tmz(adev)) { -		drm_file_err(uq_mgr->file, "Secure only supported on GFX/Compute queues\n"); -		return -EINVAL; -	} -  	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);  	if (r < 0) {  		drm_file_err(uq_mgr->file, "pm_runtime_get_sync() failed for userqueue create\n"); @@ -543,22 +526,45 @@ unlock:  	return r;  } -int amdgpu_userq_ioctl(struct drm_device *dev, void *data, -		       struct drm_file *filp) +static int amdgpu_userq_input_args_validate(struct drm_device *dev, +					union drm_amdgpu_userq *args, +					struct drm_file *filp)  { -	union drm_amdgpu_userq *args = data; -	int r; +	struct amdgpu_device *adev = drm_to_adev(dev);  	switch (args->in.op) {  	case AMDGPU_USERQ_OP_CREATE:  		if (args->in.flags & ~(AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_MASK |  				       AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE))  			return -EINVAL; -		r = amdgpu_userq_create(filp, args); -		if (r) -			drm_file_err(filp, "Failed to create usermode queue\n"); -		break; +		/* Usermode queues are only supported for GFX IP as of now */ +		if (args->in.ip_type != AMDGPU_HW_IP_GFX && +		    args->in.ip_type != AMDGPU_HW_IP_DMA && +		    args->in.ip_type != AMDGPU_HW_IP_COMPUTE) { +			drm_file_err(filp, "Usermode queue doesn't support IP type %u\n", +				     args->in.ip_type); +			return -EINVAL; +		} + +		if ((args->in.flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE) && +		    (args->in.ip_type != AMDGPU_HW_IP_GFX) && +		    (args->in.ip_type != AMDGPU_HW_IP_COMPUTE) && +		    !amdgpu_is_tmz(adev)) { +			drm_file_err(filp, "Secure only supported on GFX/Compute queues\n"); +			return -EINVAL; +		} +		if (args->in.queue_va == AMDGPU_BO_INVALID_OFFSET || +		    args->in.queue_va == 0 || +		    args->in.queue_size == 0) { +			drm_file_err(filp, "invalidate userq queue va or size\n"); +			return -EINVAL; +		} +		if (!args->in.wptr_va || !args->in.rptr_va) { +			drm_file_err(filp, "invalidate userq queue rptr or wptr\n"); +			return -EINVAL; +		} +		break;  	case AMDGPU_USERQ_OP_FREE:  		if (args->in.ip_type ||  		    args->in.doorbell_handle || @@ -571,6 +577,31 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data,  		    args->in.mqd ||  		    args->in.mqd_size)  			return -EINVAL; +		break; +	default: +		return -EINVAL; +	} + +	return 0; +} + +int amdgpu_userq_ioctl(struct drm_device *dev, void *data, +		       struct drm_file *filp) +{ +	union drm_amdgpu_userq *args = data; +	int r; + +	if (amdgpu_userq_input_args_validate(dev, args, filp) < 0) +		return -EINVAL; + +	switch (args->in.op) { +	case AMDGPU_USERQ_OP_CREATE: +		r = amdgpu_userq_create(filp, args); +		if (r) +			drm_file_err(filp, "Failed to create usermode queue\n"); +		break; + +	case AMDGPU_USERQ_OP_FREE:  		r = amdgpu_userq_destroy(filp, args->in.queue_id);  		if (r)  			drm_file_err(filp, "Failed to destroy usermode queue\n"); | 
