diff options
| author | Thomas Hellstrom <thellstrom@vmware.com> | 2009-12-22 10:53:41 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2009-12-22 19:06:24 -0500 |
| commit | 7a73ba7469cbea631050094fd14f73acebb97cf9 (patch) | |
| tree | 2c1bc2b28a395578967343e14a3a4b90c66e55f5 | |
| parent | 3d3a5b3290043618e8409f3fb68a63de6156fdd4 (diff) | |
drm/vmwgfx: Use TTM handles instead of SIDs as user-space surface handles.
Improve the command verifier to catch all occurences of surface handles,
and translate to SIDs.
This way DMA buffers and 3D surfaces share a common handle space,
which makes it possible for the kms code to differentiate.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 153 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 149 |
4 files changed, 209 insertions, 111 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 43546d09d1b0..e61bd85b6975 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
| @@ -123,6 +123,7 @@ struct vmw_sw_context{ | |||
| 123 | uint32_t last_cid; | 123 | uint32_t last_cid; |
| 124 | bool cid_valid; | 124 | bool cid_valid; |
| 125 | uint32_t last_sid; | 125 | uint32_t last_sid; |
| 126 | uint32_t sid_translation; | ||
| 126 | bool sid_valid; | 127 | bool sid_valid; |
| 127 | struct ttm_object_file *tfile; | 128 | struct ttm_object_file *tfile; |
| 128 | struct list_head validate_nodes; | 129 | struct list_head validate_nodes; |
| @@ -317,9 +318,10 @@ extern void vmw_surface_res_free(struct vmw_resource *res); | |||
| 317 | extern int vmw_surface_init(struct vmw_private *dev_priv, | 318 | extern int vmw_surface_init(struct vmw_private *dev_priv, |
| 318 | struct vmw_surface *srf, | 319 | struct vmw_surface *srf, |
| 319 | void (*res_free) (struct vmw_resource *res)); | 320 | void (*res_free) (struct vmw_resource *res)); |
| 320 | extern int vmw_user_surface_lookup(struct vmw_private *dev_priv, | 321 | extern int vmw_user_surface_lookup_handle(struct vmw_private *dev_priv, |
| 321 | struct ttm_object_file *tfile, | 322 | struct ttm_object_file *tfile, |
| 322 | int sid, struct vmw_surface **out); | 323 | uint32_t handle, |
| 324 | struct vmw_surface **out); | ||
| 323 | extern int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data, | 325 | extern int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data, |
| 324 | struct drm_file *file_priv); | 326 | struct drm_file *file_priv); |
| 325 | extern int vmw_surface_define_ioctl(struct drm_device *dev, void *data, | 327 | extern int vmw_surface_define_ioctl(struct drm_device *dev, void *data, |
| @@ -328,7 +330,7 @@ extern int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, | |||
| 328 | struct drm_file *file_priv); | 330 | struct drm_file *file_priv); |
| 329 | extern int vmw_surface_check(struct vmw_private *dev_priv, | 331 | extern int vmw_surface_check(struct vmw_private *dev_priv, |
| 330 | struct ttm_object_file *tfile, | 332 | struct ttm_object_file *tfile, |
| 331 | int id); | 333 | uint32_t handle, int *id); |
| 332 | extern void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo); | 334 | extern void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo); |
| 333 | extern int vmw_dmabuf_init(struct vmw_private *dev_priv, | 335 | extern int vmw_dmabuf_init(struct vmw_private *dev_priv, |
| 334 | struct vmw_dma_buffer *vmw_bo, | 336 | struct vmw_dma_buffer *vmw_bo, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 7e73cf51e298..2e92da567403 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
| @@ -73,21 +73,32 @@ static int vmw_cmd_cid_check(struct vmw_private *dev_priv, | |||
| 73 | 73 | ||
| 74 | static int vmw_cmd_sid_check(struct vmw_private *dev_priv, | 74 | static int vmw_cmd_sid_check(struct vmw_private *dev_priv, |
| 75 | struct vmw_sw_context *sw_context, | 75 | struct vmw_sw_context *sw_context, |
| 76 | uint32_t sid) | 76 | uint32_t *sid) |
| 77 | { | 77 | { |
| 78 | if (unlikely((!sw_context->sid_valid || sid != sw_context->last_sid) && | 78 | if (*sid == SVGA3D_INVALID_ID) |
| 79 | sid != SVGA3D_INVALID_ID)) { | 79 | return 0; |
| 80 | int ret = vmw_surface_check(dev_priv, sw_context->tfile, sid); | 80 | |
| 81 | if (unlikely((!sw_context->sid_valid || | ||
| 82 | *sid != sw_context->last_sid))) { | ||
| 83 | int real_id; | ||
| 84 | int ret = vmw_surface_check(dev_priv, sw_context->tfile, | ||
| 85 | *sid, &real_id); | ||
| 81 | 86 | ||
| 82 | if (unlikely(ret != 0)) { | 87 | if (unlikely(ret != 0)) { |
| 83 | DRM_ERROR("Could ot find or use surface %u\n", | 88 | DRM_ERROR("Could ot find or use surface 0x%08x " |
| 84 | (unsigned) sid); | 89 | "address 0x%08lx\n", |
| 90 | (unsigned int) *sid, | ||
| 91 | (unsigned long) sid); | ||
| 85 | return ret; | 92 | return ret; |
| 86 | } | 93 | } |
| 87 | 94 | ||
| 88 | sw_context->last_sid = sid; | 95 | sw_context->last_sid = *sid; |
| 89 | sw_context->sid_valid = true; | 96 | sw_context->sid_valid = true; |
| 90 | } | 97 | *sid = real_id; |
| 98 | sw_context->sid_translation = real_id; | ||
| 99 | } else | ||
| 100 | *sid = sw_context->sid_translation; | ||
| 101 | |||
| 91 | return 0; | 102 | return 0; |
| 92 | } | 103 | } |
| 93 | 104 | ||
| @@ -107,7 +118,8 @@ static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv, | |||
| 107 | return ret; | 118 | return ret; |
| 108 | 119 | ||
| 109 | cmd = container_of(header, struct vmw_sid_cmd, header); | 120 | cmd = container_of(header, struct vmw_sid_cmd, header); |
| 110 | return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.target.sid); | 121 | ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.target.sid); |
| 122 | return ret; | ||
| 111 | } | 123 | } |
| 112 | 124 | ||
| 113 | static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, | 125 | static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, |
| @@ -121,10 +133,10 @@ static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, | |||
| 121 | int ret; | 133 | int ret; |
| 122 | 134 | ||
| 123 | cmd = container_of(header, struct vmw_sid_cmd, header); | 135 | cmd = container_of(header, struct vmw_sid_cmd, header); |
| 124 | ret = vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.src.sid); | 136 | ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.src.sid); |
| 125 | if (unlikely(ret != 0)) | 137 | if (unlikely(ret != 0)) |
| 126 | return ret; | 138 | return ret; |
| 127 | return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.dest.sid); | 139 | return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.dest.sid); |
| 128 | } | 140 | } |
| 129 | 141 | ||
| 130 | static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, | 142 | static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, |
| @@ -138,10 +150,10 @@ static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, | |||
| 138 | int ret; | 150 | int ret; |
| 139 | 151 | ||
| 140 | cmd = container_of(header, struct vmw_sid_cmd, header); | 152 | cmd = container_of(header, struct vmw_sid_cmd, header); |
| 141 | ret = vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.src.sid); | 153 | ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.src.sid); |
| 142 | if (unlikely(ret != 0)) | 154 | if (unlikely(ret != 0)) |
| 143 | return ret; | 155 | return ret; |
| 144 | return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.dest.sid); | 156 | return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.dest.sid); |
| 145 | } | 157 | } |
| 146 | 158 | ||
| 147 | static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv, | 159 | static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv, |
| @@ -154,7 +166,7 @@ static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv, | |||
| 154 | } *cmd; | 166 | } *cmd; |
| 155 | 167 | ||
| 156 | cmd = container_of(header, struct vmw_sid_cmd, header); | 168 | cmd = container_of(header, struct vmw_sid_cmd, header); |
| 157 | return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.srcImage.sid); | 169 | return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.srcImage.sid); |
| 158 | } | 170 | } |
| 159 | 171 | ||
| 160 | static int vmw_cmd_present_check(struct vmw_private *dev_priv, | 172 | static int vmw_cmd_present_check(struct vmw_private *dev_priv, |
| @@ -167,7 +179,7 @@ static int vmw_cmd_present_check(struct vmw_private *dev_priv, | |||
| 167 | } *cmd; | 179 | } *cmd; |
| 168 | 180 | ||
| 169 | cmd = container_of(header, struct vmw_sid_cmd, header); | 181 | cmd = container_of(header, struct vmw_sid_cmd, header); |
| 170 | return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.sid); | 182 | return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.sid); |
| 171 | } | 183 | } |
| 172 | 184 | ||
| 173 | static int vmw_cmd_dma(struct vmw_private *dev_priv, | 185 | static int vmw_cmd_dma(struct vmw_private *dev_priv, |
| @@ -187,12 +199,7 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, | |||
| 187 | uint32_t cur_validate_node; | 199 | uint32_t cur_validate_node; |
| 188 | struct ttm_validate_buffer *val_buf; | 200 | struct ttm_validate_buffer *val_buf; |
| 189 | 201 | ||
| 190 | |||
| 191 | cmd = container_of(header, struct vmw_dma_cmd, header); | 202 | cmd = container_of(header, struct vmw_dma_cmd, header); |
| 192 | ret = vmw_cmd_sid_check(dev_priv, sw_context, cmd->dma.host.sid); | ||
| 193 | if (unlikely(ret != 0)) | ||
| 194 | return ret; | ||
| 195 | |||
| 196 | handle = cmd->dma.guest.ptr.gmrId; | 203 | handle = cmd->dma.guest.ptr.gmrId; |
| 197 | ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); | 204 | ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); |
| 198 | if (unlikely(ret != 0)) { | 205 | if (unlikely(ret != 0)) { |
| @@ -228,14 +235,23 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, | |||
| 228 | ++sw_context->cur_val_buf; | 235 | ++sw_context->cur_val_buf; |
| 229 | } | 236 | } |
| 230 | 237 | ||
| 231 | ret = vmw_user_surface_lookup(dev_priv, sw_context->tfile, | ||
