diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2011-10-04 14:13:32 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-10-05 05:17:26 -0400 |
commit | 90ff18bc3a1ff56e3948ccf7ae4031b8e9662981 (patch) | |
tree | 0bc66b9162559f40db11627b24e6ab5a60e3db1b /drivers/gpu/drm/vmwgfx | |
parent | f18c8840bef4195e6f35298b7746563f10d2d502 (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.c | 56 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 2 |
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 | ||
352 | static int do_surface_dirty_sou(struct vmw_private *dev_priv, | 353 | static 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 | ||
407 | int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, | 409 | int 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: | |||
563 | struct vmw_framebuffer_dmabuf { | 566 | struct 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 | ||
569 | void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer) | 571 | void 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 | ||
870 | try_dmabuf: | 889 | try_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 | ||