diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 74 |
1 files changed, 34 insertions, 40 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 33533d126277..73489a45decb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -2377,9 +2377,12 @@ static int vmw_cmd_dx_clear_rendertarget_view(struct vmw_private *dev_priv, { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXClearRenderTargetView) = container_of(header, typeof(*cmd), header); + struct vmw_resource *ret; - return PTR_RET(vmw_view_id_val_add(sw_context, vmw_view_rt, - cmd->body.renderTargetViewId)); + ret = vmw_view_id_val_add(sw_context, vmw_view_rt, + cmd->body.renderTargetViewId); + + return PTR_ERR_OR_ZERO(ret); } /** @@ -2396,9 +2399,12 @@ static int vmw_cmd_dx_clear_depthstencil_view(struct vmw_private *dev_priv, { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXClearDepthStencilView) = container_of(header, typeof(*cmd), header); + struct vmw_resource *ret; + + ret = vmw_view_id_val_add(sw_context, vmw_view_ds, + cmd->body.depthStencilViewId); - return PTR_RET(vmw_view_id_val_add(sw_context, vmw_view_ds, - cmd->body.depthStencilViewId)); + return PTR_ERR_OR_ZERO(ret); } static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv, @@ -2560,7 +2566,6 @@ static int vmw_cmd_dx_check_subresource(struct vmw_private *dev_priv, offsetof(typeof(*cmd), sid)); cmd = container_of(header, typeof(*cmd), header); - return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->sid, NULL); @@ -2742,9 +2747,12 @@ static int vmw_cmd_dx_genmips(struct vmw_private *dev_priv, { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXGenMips) = container_of(header, typeof(*cmd), header); + struct vmw_resource *ret; - return PTR_RET(vmw_view_id_val_add(sw_context, vmw_view_sr, - cmd->body.shaderResourceViewId)); + ret = vmw_view_id_val_add(sw_context, vmw_view_sr, + cmd->body.shaderResourceViewId); + + return PTR_ERR_OR_ZERO(ret); } /** @@ -3995,54 +4003,40 @@ void vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv) mutex_unlock(&dev_priv->cmdbuf_mutex); } -int vmw_execbuf_ioctl(struct drm_device *dev, unsigned long data, - struct drm_file *file_priv, size_t size) +int vmw_execbuf_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) { struct vmw_private *dev_priv = vmw_priv(dev); - struct drm_vmw_execbuf_arg arg; + struct drm_vmw_execbuf_arg *arg = data; int ret; - static const size_t copy_offset[] = { - offsetof(struct drm_vmw_execbuf_arg, context_handle), - sizeof(struct drm_vmw_execbuf_arg)}; struct dma_fence *in_fence = NULL; - if (unlikely(size < copy_offset[0])) { - VMW_DEBUG_USER("Invalid command size, ioctl %d\n", - DRM_VMW_EXECBUF); - return -EINVAL; - } - - if (copy_from_user(&arg, (void __user *) data, copy_offset[0]) != 0) - return -EFAULT; - /* * Extend the ioctl argument while maintaining backwards compatibility: - * We take different code paths depending on the value of arg.version. + * We take different code paths depending on the value of arg->version. + * + * Note: The ioctl argument is extended and zeropadded by core DRM. */ - if (unlikely(arg.version > DRM_VMW_EXECBUF_VERSION || - arg.version == 0)) { + if (unlikely(arg->version > DRM_VMW_EXECBUF_VERSION || + arg->version == 0)) { VMW_DEBUG_USER("Incorrect execbuf version.\n"); return -EINVAL; } - if (arg.version > 1 && - copy_from_user(&arg.context_handle, - (void __user *) (data + copy_offset[0]), - copy_offset[arg.version - 1] - copy_offset[0]) != 0) - return -EFAULT; - - switch (arg.version) { + switch (arg->version) { case 1: - arg.context_handle = (uint32_t) -1; + /* For v1 core DRM have extended + zeropadded the data */ + arg->context_handle = (uint32_t) -1; break; case 2: default: + /* For v2 and later core DRM would have correctly copied it */ break; } /* If imported a fence FD from elsewhere, then wait on it */ - if (arg.flags & DRM_VMW_EXECBUF_FLAG_IMPORT_FENCE_FD) { - in_fence = sync_file_get_fence(arg.imported_fence_fd); + if (arg->flags & DRM_VMW_EXECBUF_FLAG_IMPORT_FENCE_FD) { + in_fence = sync_file_get_fence(arg->imported_fence_fd); if (!in_fence) { VMW_DEBUG_USER("Cannot get imported fence\n"); @@ -4059,11 +4053,11 @@ int vmw_execbuf_ioctl(struct drm_device *dev, unsigned long data, return ret; ret = vmw_execbuf_process(file_priv, dev_priv, - (void __user *)(unsigned long)arg.commands, - NULL, arg.command_size, arg.throttle_us, - arg.context_handle, - (void __user *)(unsigned long)arg.fence_rep, - NULL, arg.flags); + (void __user *)(unsigned long)arg->commands, + NULL, arg->command_size, arg->throttle_us, + arg->context_handle, + (void __user *)(unsigned long)arg->fence_rep, + NULL, arg->flags); ttm_read_unlock(&dev_priv->reservation_sem); if (unlikely(ret != 0)) |