drm/vmwgfx: Add "quirk" to handling command verification exceptions
authorThomas Hellstrom <thellstrom@vmware.com>
Tue, 3 Mar 2015 07:45:04 +0000 (23:45 -0800)
committerThomas Hellstrom <thellstrom@vmware.com>
Wed, 5 Aug 2015 12:01:07 +0000 (14:01 +0200)
For certain surface copies, we don't have a user space handle for
the destination surface.  In such cases, we are going to trust that
our caller is giving us the right surface ID.

To do this case, we created a quirk flag that may be useful
in the future for handling other cases.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Sinclair Yeh <syeh@vmware.com>
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c

index b65eb02e483eacde62959ce8be136a64cdbb1766..c3f8fc97b336b5a14d84143c052bfe6a93181176 100644 (file)
@@ -341,6 +341,8 @@ enum vmw_display_unit_type {
 };
 
 
+#define VMW_QUIRK_SCREENTARGET (1U << 0)
+
 struct vmw_sw_context{
        struct drm_open_hash res_ht;
        bool res_ht_initialized;
@@ -363,6 +365,7 @@ struct vmw_sw_context{
        struct vmw_resource *error_resource;
        struct vmw_ctx_binding_state staged_bindings;
        struct list_head staged_cmd_res;
+       uint32_t quirks;
 };
 
 struct vmw_legacy_display;
@@ -831,6 +834,7 @@ extern int vmw_execbuf_process(struct drm_file *file_priv,
                               void *kernel_commands,
                               uint32_t command_size,
                               uint64_t throttle_us,
+                              uint32_t quirks,
                               struct drm_vmw_fence_rep __user
                               *user_fence_rep,
                               struct vmw_fence_obj **out_fence);
index 0792d8d5931593f9ebf171b0d62802ebac84cd41..497ad6aecfbbc07735d238bece6edfe28e5e1639 100644 (file)
@@ -679,6 +679,10 @@ static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv,
                                &cmd->body.src.sid, NULL);
        if (unlikely(ret != 0))
                return ret;
+
+       if (sw_context->quirks & VMW_QUIRK_SCREENTARGET)
+               return 0;
+
        return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
                                 user_surface_converter,
                                 &cmd->body.dest.sid, NULL);
@@ -1260,6 +1264,9 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv,
        if (unlikely(suffix->maximumOffset > bo_size))
                suffix->maximumOffset = bo_size;
 
+       if (sw_context->quirks & VMW_QUIRK_SCREENTARGET)
+               goto out_no_surface;
+
        ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
                                user_surface_converter, &cmd->dma.host.sid,
                                NULL);
@@ -2544,6 +2551,7 @@ int vmw_execbuf_process(struct drm_file *file_priv,
                        void *kernel_commands,
                        uint32_t command_size,
                        uint64_t throttle_us,
+                       uint32_t quirks,
                        struct drm_vmw_fence_rep __user *user_fence_rep,
                        struct vmw_fence_obj **out_fence)
 {
@@ -2598,6 +2606,7 @@ int vmw_execbuf_process(struct drm_file *file_priv,
        sw_context->fp = vmw_fpriv(file_priv);
        sw_context->cur_reloc = 0;
        sw_context->cur_val_buf = 0;
+       sw_context->quirks = quirks;
        INIT_LIST_HEAD(&sw_context->resource_list);
        sw_context->cur_query_bo = dev_priv->pinned_bo;
        sw_context->last_query_ctx = NULL;
@@ -2904,6 +2913,7 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
        ret = vmw_execbuf_process(file_priv, dev_priv,
                                  (void __user *)(unsigned long)arg->commands,
                                  NULL, arg->command_size, arg->throttle_us,
+                                 0,
                                  (void __user *)(unsigned long)arg->fence_rep,
                                  NULL);
        ttm_read_unlock(&dev_priv->reservation_sem);
index cac17c240ec0c7e882ef5d9cfbfdd9f0fd7c4b51..7566a5a14004435255408d7b9d635fff928a1192 100644 (file)
@@ -993,7 +993,7 @@ int vmw_kms_generic_present(struct vmw_private *dev_priv,
                fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num;
                cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
                ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
-                                         fifo_size, 0, NULL, NULL);
+                                         fifo_size, 0, 0, NULL, NULL);
 
                if (unlikely(ret != 0))
                        break;
@@ -1121,7 +1121,7 @@ int vmw_kms_readback(struct vmw_private *dev_priv,
        fifo_size = sizeof(*cmd) + sizeof(*blits) * blits_pos;
 
        ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, fifo_size,
-                                 0, user_fence_rep, NULL);
+                                 0, 0, user_fence_rep, NULL);
 
        kfree(cmd);
 
index 807fc87c0c965f3318eb67e967eca7a672f065bb..0d06d86e432a39c167d6eb8eb6260cad8579e131 100644 (file)
@@ -621,7 +621,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
                fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num;
                cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
                ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
-                                         fifo_size, 0, NULL, out_fence);
+                                         fifo_size, 0, 0, NULL, out_fence);
 
                if (unlikely(ret != 0))
                        break;
@@ -827,7 +827,7 @@ static int do_dmabuf_define_gmrfb(struct drm_file *file_priv,
        cmd->body.ptr.offset = 0;
 
        ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
-                                 fifo_size, 0, NULL, NULL);
+                                 fifo_size, 0, 0, NULL, NULL);
 
        kfree(cmd);
 
@@ -919,7 +919,7 @@ int vmw_kms_sou_do_dmabuf_dirty(struct drm_file *file_priv,
 
                fifo_size = sizeof(*blits) * hit_num;
                ret = vmw_execbuf_process(file_priv, dev_priv, NULL, blits,
-                                         fifo_size, 0, NULL, out_fence);
+                                         fifo_size, 0, 0, NULL, out_fence);
 
                if (unlikely(ret != 0))
                        break;