Commit 90ff18bc authored by Thomas Hellstrom's avatar Thomas Hellstrom Committed by Dave Airlie

vmwgfx: Make sure we always have a user-space handle to use for objects that...

vmwgfx: Make sure we always have a user-space handle to use for objects that are backing kms framebuffers.
Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: default avatarJakob Bornecrantz <jakob@vmware.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent f18c8840
...@@ -345,11 +345,13 @@ void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer) ...@@ -345,11 +345,13 @@ void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer)
drm_master_put(&vfbs->master); drm_master_put(&vfbs->master);
drm_framebuffer_cleanup(framebuffer); drm_framebuffer_cleanup(framebuffer);
vmw_surface_unreference(&vfbs->surface); vmw_surface_unreference(&vfbs->surface);
ttm_base_object_unref(&vfbs->base.user_obj);
kfree(vfbs); kfree(vfbs);
} }
static int do_surface_dirty_sou(struct vmw_private *dev_priv, static int do_surface_dirty_sou(struct vmw_private *dev_priv,
struct drm_file *file_priv,
struct vmw_framebuffer *framebuffer, struct vmw_framebuffer *framebuffer,
struct vmw_surface *surf, struct vmw_surface *surf,
unsigned flags, unsigned color, unsigned flags, unsigned color,
...@@ -359,7 +361,7 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, ...@@ -359,7 +361,7 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
int left = clips->x2, right = clips->x1; int left = clips->x2, right = clips->x1;
int top = clips->y2, bottom = clips->y1; int top = clips->y2, bottom = clips->y1;
size_t fifo_size; size_t fifo_size;
int i; int i, ret;
struct { struct {
SVGA3dCmdHeader header; SVGA3dCmdHeader header;
...@@ -368,18 +370,16 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, ...@@ -368,18 +370,16 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
fifo_size = sizeof(*cmd); fifo_size = sizeof(*cmd);
cmd = vmw_fifo_reserve(dev_priv, fifo_size); cmd = kzalloc(fifo_size, GFP_KERNEL);
if (unlikely(cmd == NULL)) { if (unlikely(cmd == NULL)) {
DRM_ERROR("Fifo reserve failed.\n"); DRM_ERROR("Temporary fifo memory alloc failed.\n");
return -ENOMEM; return -ENOMEM;
} }
memset(cmd, 0, fifo_size);
cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN); cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN);
cmd->header.size = cpu_to_le32(sizeof(cmd->body)); cmd->header.size = cpu_to_le32(sizeof(cmd->body));
cmd->body.srcImage.sid = cpu_to_le32(surf->res.id); cmd->body.srcImage.sid = cpu_to_le32(framebuffer->user_handle);
cmd->body.destScreenId = SVGA_ID_INVALID; /* virtual coords */ cmd->body.destScreenId = SVGA_ID_INVALID; /* virtual coords */
for (i = 0; i < num_clips; i++, clips += inc) { 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,9 +399,11 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
cmd->body.destRect.top = top; cmd->body.destRect.top = top;
cmd->body.destRect.bottom = bottom; cmd->body.destRect.bottom = bottom;
vmw_fifo_commit(dev_priv, fifo_size); ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, fifo_size,
0, NULL);
kfree(cmd);
return 0; return ret;
} }
int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
...@@ -440,7 +442,7 @@ int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, ...@@ -440,7 +442,7 @@ int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
inc = 2; /* skip source rects */ inc = 2; /* skip source rects */
} }
ret = do_surface_dirty_sou(dev_priv, &vfbs->base, surf, ret = do_surface_dirty_sou(dev_priv, file_priv, &vfbs->base, surf,
flags, color, flags, color,
clips, num_clips, inc); clips, num_clips, inc);
...@@ -535,6 +537,7 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, ...@@ -535,6 +537,7 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
vfbs->base.base.width = mode_cmd->width; vfbs->base.base.width = mode_cmd->width;
vfbs->base.base.height = mode_cmd->height; vfbs->base.base.height = mode_cmd->height;
vfbs->surface = surface; vfbs->surface = surface;
vfbs->base.user_handle = mode_cmd->handle;
vfbs->master = drm_master_get(file_priv->master); vfbs->master = drm_master_get(file_priv->master);
mutex_lock(&vmaster->fb_surf_mutex); mutex_lock(&vmaster->fb_surf_mutex);
...@@ -563,7 +566,6 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, ...@@ -563,7 +566,6 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
struct vmw_framebuffer_dmabuf { struct vmw_framebuffer_dmabuf {
struct vmw_framebuffer base; struct vmw_framebuffer base;
struct vmw_dma_buffer *buffer; struct vmw_dma_buffer *buffer;
uint32_t handle;
}; };
void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer) void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer)
...@@ -573,6 +575,7 @@ void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer) ...@@ -573,6 +575,7 @@ void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer)
drm_framebuffer_cleanup(framebuffer); drm_framebuffer_cleanup(framebuffer);
vmw_dmabuf_unreference(&vfbd->buffer); vmw_dmabuf_unreference(&vfbd->buffer);
ttm_base_object_unref(&vfbd->base.user_obj);
kfree(vfbd); kfree(vfbd);
} }
...@@ -620,8 +623,6 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv, ...@@ -620,8 +623,6 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv,
struct drm_clip_rect *clips, struct drm_clip_rect *clips,
unsigned num_clips, int increment) unsigned num_clips, int increment)
{ {
struct vmw_framebuffer_dmabuf *vfbd =
vmw_framebuffer_to_vfbd(&framebuffer->base);
size_t fifo_size; size_t fifo_size;
int i, ret; int i, ret;
...@@ -647,7 +648,7 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv, ...@@ -647,7 +648,7 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv,
cmd->body.format.colorDepth = framebuffer->base.depth; cmd->body.format.colorDepth = framebuffer->base.depth;
cmd->body.format.reserved = 0; cmd->body.format.reserved = 0;
cmd->body.bytesPerLine = framebuffer->base.pitch; cmd->body.bytesPerLine = framebuffer->base.pitch;
cmd->body.ptr.gmrId = vfbd->handle; cmd->body.ptr.gmrId = framebuffer->user_handle;
cmd->body.ptr.offset = 0; cmd->body.ptr.offset = 0;
blits = (void *)&cmd[1]; blits = (void *)&cmd[1];
...@@ -802,7 +803,7 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv, ...@@ -802,7 +803,7 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
} }
vfbd->base.dmabuf = true; vfbd->base.dmabuf = true;
vfbd->buffer = dmabuf; vfbd->buffer = dmabuf;
vfbd->handle = mode_cmd->handle; vfbd->base.user_handle = mode_cmd->handle;
*out = &vfbd->base; *out = &vfbd->base;
return 0; return 0;
...@@ -828,6 +829,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, ...@@ -828,6 +829,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
struct vmw_framebuffer *vfb = NULL; struct vmw_framebuffer *vfb = NULL;
struct vmw_surface *surface = NULL; struct vmw_surface *surface = NULL;
struct vmw_dma_buffer *bo = NULL; struct vmw_dma_buffer *bo = NULL;
struct ttm_base_object *user_obj;
u64 required_size; u64 required_size;
int ret; int ret;
...@@ -843,6 +845,21 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, ...@@ -843,6 +845,21 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
return NULL; return NULL;
} }
/*
* Take a reference on the user object of the resource
* backing the kms fb. This ensures that user-space handle
* lookups on that resource will always work as long as
* it's registered with a kms framebuffer. This is important,
* since vmw_execbuf_process identifies resources in the
* command stream using user-space handles.
*/
user_obj = ttm_base_object_lookup(tfile, mode_cmd->handle);
if (unlikely(user_obj == NULL)) {
DRM_ERROR("Could not locate requested kms frame buffer.\n");
return ERR_PTR(-ENOENT);
}
/** /**
* End conditioned code. * End conditioned code.
*/ */
...@@ -863,8 +880,10 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, ...@@ -863,8 +880,10 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
if (ret) { if (ret) {
DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret); DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret);
ttm_base_object_unref(&user_obj);
return ERR_PTR(ret); return ERR_PTR(ret);
} } else
vfb->user_obj = user_obj;
return &vfb->base; return &vfb->base;
try_dmabuf: try_dmabuf:
...@@ -884,8 +903,10 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, ...@@ -884,8 +903,10 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
if (ret) { if (ret) {
DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret); DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret);
ttm_base_object_unref(&user_obj);
return ERR_PTR(ret); return ERR_PTR(ret);
} } else
vfb->user_obj = user_obj;
return &vfb->base; return &vfb->base;
...@@ -893,6 +914,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, ...@@ -893,6 +914,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
DRM_ERROR("surface not marked as scanout\n"); DRM_ERROR("surface not marked as scanout\n");
/* vmw_user_surface_lookup takes one ref */ /* vmw_user_surface_lookup takes one ref */
vmw_surface_unreference(&surface); vmw_surface_unreference(&surface);
ttm_base_object_unref(&user_obj);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
...@@ -1011,7 +1033,7 @@ int vmw_kms_readback(struct vmw_private *dev_priv, ...@@ -1011,7 +1033,7 @@ int vmw_kms_readback(struct vmw_private *dev_priv,
cmd->body.format.colorDepth = vfb->base.depth; cmd->body.format.colorDepth = vfb->base.depth;
cmd->body.format.reserved = 0; cmd->body.format.reserved = 0;
cmd->body.bytesPerLine = vfb->base.pitch; cmd->body.bytesPerLine = vfb->base.pitch;
cmd->body.ptr.gmrId = vfbd->handle; cmd->body.ptr.gmrId = vfb->user_handle;
cmd->body.ptr.offset = 0; cmd->body.ptr.offset = 0;
blits = (void *)&cmd[1]; blits = (void *)&cmd[1];
......
...@@ -48,6 +48,8 @@ struct vmw_framebuffer { ...@@ -48,6 +48,8 @@ struct vmw_framebuffer {
int (*pin)(struct vmw_framebuffer *fb); int (*pin)(struct vmw_framebuffer *fb);
int (*unpin)(struct vmw_framebuffer *fb); int (*unpin)(struct vmw_framebuffer *fb);
bool dmabuf; bool dmabuf;
struct ttm_base_object *user_obj;
uint32_t user_handle;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment