Commit c0d5fb4d authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-qemu-20160921' of git://git.kraxel.org/linux into drm-next

bugfixes for qemu (bochs, qxl and virtio-gpu) drm drivers

* tag 'drm-qemu-20160921' of git://git.kraxel.org/linux:
  drm/virtio: add real fence context and seqno
  drm/virtio: drop virtio_gpu_execbuffer_ioctl() wrapping
  virtio-gpu: avoid possible NULL pointer dereference
  drm/qxl: reapply cursor after SetCrtc calls
  bochs: ignore device if there isn't enougth memory
parents ca09fb9f 30b9c96c
...@@ -163,8 +163,15 @@ static int bochs_kick_out_firmware_fb(struct pci_dev *pdev) ...@@ -163,8 +163,15 @@ static int bochs_kick_out_firmware_fb(struct pci_dev *pdev)
static int bochs_pci_probe(struct pci_dev *pdev, static int bochs_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
unsigned long fbsize;
int ret; int ret;
fbsize = pci_resource_len(pdev, 0);
if (fbsize < 4 * 1024 * 1024) {
DRM_ERROR("less than 4 MB video memory, ignoring device\n");
return -ENOMEM;
}
ret = bochs_kick_out_firmware_fb(pdev); ret = bochs_kick_out_firmware_fb(pdev);
if (ret) if (ret)
return ret; return ret;
......
...@@ -211,6 +211,7 @@ static void qxl_crtc_destroy(struct drm_crtc *crtc) ...@@ -211,6 +211,7 @@ static void qxl_crtc_destroy(struct drm_crtc *crtc)
struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc); struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc);
drm_crtc_cleanup(crtc); drm_crtc_cleanup(crtc);
qxl_bo_unref(&qxl_crtc->cursor_bo);
kfree(qxl_crtc); kfree(qxl_crtc);
} }
...@@ -296,6 +297,52 @@ qxl_hide_cursor(struct qxl_device *qdev) ...@@ -296,6 +297,52 @@ qxl_hide_cursor(struct qxl_device *qdev)
return 0; return 0;
} }
static int qxl_crtc_apply_cursor(struct drm_crtc *crtc)
{
struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct qxl_device *qdev = dev->dev_private;
struct qxl_cursor_cmd *cmd;
struct qxl_release *release;
int ret = 0;
if (!qcrtc->cursor_bo)
return 0;
ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd),
QXL_RELEASE_CURSOR_CMD,
&release, NULL);
if (ret)
return ret;
ret = qxl_release_list_add(release, qcrtc->cursor_bo);
if (ret)
goto out_free_release;
ret = qxl_release_reserve_list(release, false);
if (ret)
goto out_free_release;
cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
cmd->type = QXL_CURSOR_SET;
cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x;
cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y;
cmd->u.set.shape = qxl_bo_physical_address(qdev, qcrtc->cursor_bo, 0);
cmd->u.set.visible = 1;
qxl_release_unmap(qdev, release, &cmd->release_info);
qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
qxl_release_fence_buffer_objects(release);
return ret;
out_free_release:
qxl_release_free(qdev, release);
return ret;
}
static int qxl_crtc_cursor_set2(struct drm_crtc *crtc, static int qxl_crtc_cursor_set2(struct drm_crtc *crtc,
struct drm_file *file_priv, struct drm_file *file_priv,
uint32_t handle, uint32_t handle,
...@@ -400,7 +447,8 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc, ...@@ -400,7 +447,8 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc,
} }
drm_gem_object_unreference_unlocked(obj); drm_gem_object_unreference_unlocked(obj);
qxl_bo_unref(&cursor_bo); qxl_bo_unref (&qcrtc->cursor_bo);
qcrtc->cursor_bo = cursor_bo;
return ret; return ret;
...@@ -655,6 +703,12 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, ...@@ -655,6 +703,12 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc,
bo->surf.stride, bo->surf.format); bo->surf.stride, bo->surf.format);
qxl_io_create_primary(qdev, 0, bo); qxl_io_create_primary(qdev, 0, bo);
bo->is_primary = true; bo->is_primary = true;
ret = qxl_crtc_apply_cursor(crtc);
if (ret) {
DRM_ERROR("could not set cursor after modeset");
ret = 0;
}
} }
if (bo->is_primary) { if (bo->is_primary) {
......
...@@ -137,6 +137,7 @@ struct qxl_crtc { ...@@ -137,6 +137,7 @@ struct qxl_crtc {
int cur_y; int cur_y;
int hot_spot_x; int hot_spot_x;
int hot_spot_y; int hot_spot_y;
struct qxl_bo *cursor_bo;
}; };
struct qxl_output { struct qxl_output {
......
...@@ -75,6 +75,7 @@ typedef void (*virtio_gpu_resp_cb)(struct virtio_gpu_device *vgdev, ...@@ -75,6 +75,7 @@ typedef void (*virtio_gpu_resp_cb)(struct virtio_gpu_device *vgdev,
struct virtio_gpu_fence_driver { struct virtio_gpu_fence_driver {
atomic64_t last_seq; atomic64_t last_seq;
uint64_t sync_seq; uint64_t sync_seq;
uint64_t context;
struct list_head fences; struct list_head fences;
spinlock_t lock; spinlock_t lock;
}; };
......
...@@ -89,7 +89,7 @@ int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, ...@@ -89,7 +89,7 @@ int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
(*fence)->drv = drv; (*fence)->drv = drv;
(*fence)->seq = ++drv->sync_seq; (*fence)->seq = ++drv->sync_seq;
fence_init(&(*fence)->f, &virtio_fence_ops, &drv->lock, fence_init(&(*fence)->f, &virtio_fence_ops, &drv->lock,
0, (*fence)->seq); drv->context, (*fence)->seq);
fence_get(&(*fence)->f); fence_get(&(*fence)->f);
list_add_tail(&(*fence)->node, &drv->fences); list_add_tail(&(*fence)->node, &drv->fences);
spin_unlock_irqrestore(&drv->lock, irq_flags); spin_unlock_irqrestore(&drv->lock, irq_flags);
......
...@@ -89,10 +89,16 @@ static void virtio_gpu_unref_list(struct list_head *head) ...@@ -89,10 +89,16 @@ static void virtio_gpu_unref_list(struct list_head *head)
} }
} }
static int virtio_gpu_execbuffer(struct drm_device *dev, /*
struct drm_virtgpu_execbuffer *exbuf, * Usage of execbuffer:
* Relocations need to take into account the full VIRTIO_GPUDrawable size.
* However, the command as passed from user space must *not* contain the initial
* VIRTIO_GPUReleaseInfo struct (first XXX bytes)
*/
static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
struct drm_file *drm_file) struct drm_file *drm_file)
{ {
struct drm_virtgpu_execbuffer *exbuf = data;
struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_device *vgdev = dev->dev_private;
struct virtio_gpu_fpriv *vfpriv = drm_file->driver_priv; struct virtio_gpu_fpriv *vfpriv = drm_file->driver_priv;
struct drm_gem_object *gobj; struct drm_gem_object *gobj;
...@@ -177,20 +183,6 @@ static int virtio_gpu_execbuffer(struct drm_device *dev, ...@@ -177,20 +183,6 @@ static int virtio_gpu_execbuffer(struct drm_device *dev,
return ret; return ret;
} }
/*
* Usage of execbuffer:
* Relocations need to take into account the full VIRTIO_GPUDrawable size.
* However, the command as passed from user space must *not* contain the initial
* VIRTIO_GPUReleaseInfo struct (first XXX bytes)
*/
static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_virtgpu_execbuffer *execbuffer = data;
return virtio_gpu_execbuffer(dev, execbuffer, file_priv);
}
static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data, static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv) struct drm_file *file_priv)
{ {
......
...@@ -159,6 +159,7 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -159,6 +159,7 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags)
virtio_gpu_init_vq(&vgdev->ctrlq, virtio_gpu_dequeue_ctrl_func); virtio_gpu_init_vq(&vgdev->ctrlq, virtio_gpu_dequeue_ctrl_func);
virtio_gpu_init_vq(&vgdev->cursorq, virtio_gpu_dequeue_cursor_func); virtio_gpu_init_vq(&vgdev->cursorq, virtio_gpu_dequeue_cursor_func);
vgdev->fence_drv.context = fence_context_alloc(1);
spin_lock_init(&vgdev->fence_drv.lock); spin_lock_init(&vgdev->fence_drv.lock);
INIT_LIST_HEAD(&vgdev->fence_drv.fences); INIT_LIST_HEAD(&vgdev->fence_drv.fences);
INIT_LIST_HEAD(&vgdev->cap_cache); INIT_LIST_HEAD(&vgdev->cap_cache);
......
...@@ -76,7 +76,8 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, ...@@ -76,7 +76,8 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane,
output = drm_crtc_to_virtio_gpu_output(plane->state->crtc); output = drm_crtc_to_virtio_gpu_output(plane->state->crtc);
if (old_state->crtc) if (old_state->crtc)
output = drm_crtc_to_virtio_gpu_output(old_state->crtc); output = drm_crtc_to_virtio_gpu_output(old_state->crtc);
WARN_ON(!output); if (WARN_ON(!output))
return;
if (plane->state->fb) { if (plane->state->fb) {
vgfb = to_virtio_gpu_framebuffer(plane->state->fb); vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
...@@ -129,7 +130,8 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, ...@@ -129,7 +130,8 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane,
output = drm_crtc_to_virtio_gpu_output(plane->state->crtc); output = drm_crtc_to_virtio_gpu_output(plane->state->crtc);
if (old_state->crtc) if (old_state->crtc)
output = drm_crtc_to_virtio_gpu_output(old_state->crtc); output = drm_crtc_to_virtio_gpu_output(old_state->crtc);
WARN_ON(!output); if (WARN_ON(!output))
return;
if (plane->state->fb) { if (plane->state->fb) {
vgfb = to_virtio_gpu_framebuffer(plane->state->fb); vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
......
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