aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vmwgfx
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2011-10-04 14:13:32 -0400
committerDave Airlie <airlied@redhat.com>2011-10-05 05:17:26 -0400
commit90ff18bc3a1ff56e3948ccf7ae4031b8e9662981 (patch)
tree0bc66b9162559f40db11627b24e6ab5a60e3db1b /drivers/gpu/drm/vmwgfx
parentf18c8840bef4195e6f35298b7746563f10d2d502 (diff)
vmwgfx: Make sure we always have a user-space handle to use for objects that are backing kms framebuffers.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Jakob Bornecrantz <jakob@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx')
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c56
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.h2
2 files changed, 41 insertions, 17 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 41916b58a3fb..b4b9aa9fa9ed 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -345,11 +345,13 @@ void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer)
345 drm_master_put(&vfbs->master); 345 drm_master_put(&vfbs->master);
346 drm_framebuffer_cleanup(framebuffer); 346 drm_framebuffer_cleanup(framebuffer);
347 vmw_surface_unreference(&vfbs->surface); 347 vmw_surface_unreference(&vfbs->surface);
348 ttm_base_object_unref(&vfbs->base.user_obj);
348 349
349 kfree(vfbs); 350 kfree(vfbs);
350} 351}
351 352
352static int do_surface_dirty_sou(struct vmw_private *dev_priv, 353static int do_surface_dirty_sou(struct vmw_private *dev_priv,
354 struct drm_file *file_priv,
353 struct vmw_framebuffer *framebuffer, 355 struct vmw_framebuffer *framebuffer,
354 struct vmw_surface *surf, 356 struct vmw_surface *surf,
355 unsigned flags, unsigned color, 357 unsigned flags, unsigned color,
@@ -359,7 +361,7 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
359 int left = clips->x2, right = clips->x1; 361 int left = clips->x2, right = clips->x1;
360 int top = clips->y2, bottom = clips->y1; 362 int top = clips->y2, bottom = clips->y1;
361 size_t fifo_size; 363 size_t fifo_size;
362 int i; 364 int i, ret;
363 365
364 struct { 366 struct {
365 SVGA3dCmdHeader header; 367 SVGA3dCmdHeader header;
@@ -368,18 +370,16 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
368 370
369 371
370 fifo_size = sizeof(*cmd); 372 fifo_size = sizeof(*cmd);
371 cmd = vmw_fifo_reserve(dev_priv, fifo_size); 373 cmd = kzalloc(fifo_size, GFP_KERNEL);
372 if (unlikely(cmd == NULL)) { 374 if (unlikely(cmd == NULL)) {
373 DRM_ERROR("Fifo reserve failed.\n"); 375 DRM_ERROR("Temporary fifo memory alloc failed.\n");
374 return -ENOMEM; 376 return -ENOMEM;
375 } 377 }
376 378
377 memset(cmd, 0, fifo_size);
378
379 cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN); 379 cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN);
380 cmd->header.size = cpu_to_le32(sizeof(cmd->body)); 380 cmd->header.size = cpu_to_le32(sizeof(cmd->body));
381 381
382 cmd->body.srcImage.sid = cpu_to_le32(surf->res.id); 382 cmd->body.srcImage.sid = cpu_to_le32(framebuffer->user_handle);
383 cmd->body.destScreenId = SVGA_ID_INVALID; /* virtual coords */ 383 cmd->body.destScreenId = SVGA_ID_INVALID; /* virtual coords */
384 384
385 for (i = 0; i < num_clips; i++, clips += inc) { 385 for (i = 0; i < num_clips; i++, clips += inc) {
@@ -399,9 +399,11 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
399 cmd->body.destRect.top = top; 399 cmd->body.destRect.top = top;
400 cmd->body.destRect.bottom = bottom; 400 cmd->body.destRect.bottom = bottom;
401 401
402 vmw_fifo_commit(dev_priv, fifo_size); 402 ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, fifo_size,
403 0, NULL);
404 kfree(cmd);
403 405
404 return 0; 406 return ret;
405} 407}
406 408
407int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, 409int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
@@ -440,7 +442,7 @@ int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
440 inc = 2; /* skip source rects */ 442 inc = 2; /* skip source rects */
441 } 443 }
442 444
443 ret = do_surface_dirty_sou(dev_priv, &vfbs->base, surf, 445 ret = do_surface_dirty_sou(dev_priv, file_priv, &vfbs->base, surf,
444 flags, color, 446 flags, color,
445 clips, num_clips, inc); 447 clips, num_clips, inc);
446 448
@@ -535,6 +537,7 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
535 vfbs->base.base.width = mode_cmd->width; 537 vfbs->base.base.width = mode_cmd->width;
536 vfbs->base.base.height = mode_cmd->height; 538 vfbs->base.base.height = mode_cmd->height;
537 vfbs->surface = surface; 539 vfbs->surface = surface;
540 vfbs->base.user_handle = mode_cmd->handle;
538 vfbs->master = drm_master_get(file_priv->master); 541 vfbs->master = drm_master_get(file_priv->master);
539 542
540 mutex_lock(&vmaster->fb_surf_mutex); 543 mutex_lock(&vmaster->fb_surf_mutex);
@@ -563,7 +566,6 @@ out_err1:
563struct vmw_framebuffer_dmabuf { 566struct vmw_framebuffer_dmabuf {
564 struct vmw_framebuffer base; 567 struct vmw_framebuffer base;
565 struct vmw_dma_buffer *buffer; 568 struct vmw_dma_buffer *buffer;
566 uint32_t handle;
567}; 569};
568 570
569void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer) 571void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer)
@@ -573,6 +575,7 @@ void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer)
573 575
574 drm_framebuffer_cleanup(framebuffer); 576 drm_framebuffer_cleanup(framebuffer);
575 vmw_dmabuf_unreference(&vfbd->buffer); 577 vmw_dmabuf_unreference(&vfbd->buffer);
578 ttm_base_object_unref(&vfbd->base.user_obj);
576 579
577 kfree(vfbd); 580 kfree(vfbd);
578} 581}
@@ -620,8 +623,6 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv,
620 struct drm_clip_rect *clips, 623 struct drm_clip_rect *clips,
621 unsigned num_clips, int increment) 624 unsigned num_clips, int increment)
622{ 625{
623 struct vmw_framebuffer_dmabuf *vfbd =
624 vmw_framebuffer_to_vfbd(&framebuffer->base);
625 size_t fifo_size; 626 size_t fifo_size;
626 int i, ret; 627 int i, ret;
627 628
@@ -647,7 +648,7 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv,
647 cmd->body.format.colorDepth = framebuffer->base.depth; 648 cmd->body.format.colorDepth = framebuffer->base.depth;
648 cmd->body.format.reserved = 0; 649 cmd->body.format.reserved = 0;
649 cmd->body.bytesPerLine = framebuffer->base.pitch; 650 cmd->body.bytesPerLine = framebuffer->base.pitch;
650 cmd->body.ptr.gmrId = vfbd->handle; 651 cmd->body.ptr.gmrId = framebuffer->user_handle;
651 cmd->body.ptr.offset = 0; 652 cmd->body.ptr.offset = 0;
652 653
653 blits = (void *)&cmd[1]; 654 blits = (void *)&cmd[1];
@@ -802,7 +803,7 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
802 } 803 }
803 vfbd->base.dmabuf = true; 804 vfbd->base.dmabuf = true;
804 vfbd->buffer = dmabuf; 805 vfbd->buffer = dmabuf;
805 vfbd->handle = mode_cmd->handle; 806 vfbd->base.user_handle = mode_cmd->handle;
806 *out = &vfbd->base; 807 *out = &vfbd->base;
807 808
808 return 0; 809 return 0;
@@ -828,6 +829,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
828 struct vmw_framebuffer *vfb = NULL; 829 struct vmw_framebuffer *vfb = NULL;
829 struct vmw_surface *surface = NULL; 830 struct vmw_surface *surface = NULL;
830 struct vmw_dma_buffer *bo = NULL; 831 struct vmw_dma_buffer *bo = NULL;
832 struct ttm_base_object *user_obj;
831 u64 required_size; 833 u64 required_size;
832 int ret; 834 int ret;
833 835
@@ -843,6 +845,21 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
843 return NULL; 845 return NULL;
844 } 846 }
845 847
848 /*
849 * Take a reference on the user object of the resource
850 * backing the kms fb. This ensures that user-space handle
851 * lookups on that resource will always work as long as
852 * it's registered with a kms framebuffer. This is important,
853 * since vmw_execbuf_process identifies resources in the
854 * command stream using user-space handles.
855 */
856
857 user_obj = ttm_base_object_lookup(tfile, mode_cmd->handle);
858 if (unlikely(user_obj == NULL)) {
859 DRM_ERROR("Could not locate requested kms frame buffer.\n");
860 return ERR_PTR(-ENOENT);
861 }
862
846 /** 863 /**
847 * End conditioned code. 864 * End conditioned code.
848 */ 865 */
@@ -863,8 +880,10 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
863 880
864 if (ret) { 881 if (ret) {
865 DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret); 882 DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret);
883 ttm_base_object_unref(&user_obj);
866 return ERR_PTR(ret); 884 return ERR_PTR(ret);
867 } 885 } else
886 vfb->user_obj = user_obj;
868 return &vfb->base; 887 return &vfb->base;
869 888
870try_dmabuf: 889try_dmabuf:
@@ -884,8 +903,10 @@ try_dmabuf:
884 903
885 if (ret) { 904 if (ret) {
886 DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret); 905 DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret);
906 ttm_base_object_unref(&user_obj);
887 return ERR_PTR(ret); 907 return ERR_PTR(ret);
888 } 908 } else
909 vfb->user_obj = user_obj;
889 910
890 return &vfb->base; 911 return &vfb->base;
891 912
@@ -893,6 +914,7 @@ err_not_scanout:
893 DRM_ERROR("surface not marked as scanout\n"); 914 DRM_ERROR("surface not marked as scanout\n");
894 /* vmw_user_surface_lookup takes one ref */ 915 /* vmw_user_surface_lookup takes one ref */
895 vmw_surface_unreference(&surface); 916 vmw_surface_unreference(&surface);
917 ttm_base_object_unref(&user_obj);
896 918
897 return ERR_PTR(-EINVAL); 919 return ERR_PTR(-EINVAL);
898} 920}
@@ -1011,7 +1033,7 @@ int vmw_kms_readback(struct vmw_private *dev_priv,
1011 cmd->body.format.colorDepth = vfb->base.depth; 1033 cmd->body.format.colorDepth = vfb->base.depth;
1012 cmd->body.format.reserved = 0; 1034 cmd->body.format.reserved = 0;
1013 cmd->body.bytesPerLine = vfb->base.pitch; 1035 cmd->body.bytesPerLine = vfb->base.pitch;
1014 cmd->body.ptr.gmrId = vfbd->handle; 1036 cmd->body.ptr.gmrId = vfb->user_handle;
1015 cmd->body.ptr.offset = 0; 1037 cmd->body.ptr.offset = 0;
1016 1038
1017 blits = (void *)&cmd[1]; 1039 blits = (void *)&cmd[1];
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index 08d2630ac3a7..db0b901f8c3f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -48,6 +48,8 @@ struct vmw_framebuffer {
48 int (*pin)(struct vmw_framebuffer *fb); 48 int (*pin)(struct vmw_framebuffer *fb);
49 int (*unpin)(struct vmw_framebuffer *fb); 49 int (*unpin)(struct vmw_framebuffer *fb);
50 bool dmabuf; 50 bool dmabuf;
51 struct ttm_base_object *user_obj;
52 uint32_t user_handle;
51}; 53};
52 54
53 55