summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-09-28 13:23:07 +1000
committerDave Airlie <airlied@redhat.com>2016-09-28 13:23:07 +1000
commitc0d5fb4d0d9224ccaad0475c9b58740873970e7e (patch)
tree202ee565e7d873f6580b85251aba75a00bac1fc2
parentca09fb9f60b5f3ab2d57e761aaeea89a5147d784 (diff)
parent30b9c96cf7b44d53b9165649c8be34ac234be324 (diff)
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
-rw-r--r--drivers/gpu/drm/bochs/bochs_drv.c7
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c56
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.h1
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.h1
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_fence.c2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_ioctl.c24
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_kms.c1
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_plane.c6
8 files changed, 78 insertions, 20 deletions
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
index 277654abe0f7..534227df23f3 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -163,8 +163,15 @@ static int bochs_kick_out_firmware_fb(struct pci_dev *pdev)
static int bochs_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
+ unsigned long fbsize;
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);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 3aef12742a53..a61c0d460ec2 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -211,6 +211,7 @@ static void qxl_crtc_destroy(struct drm_crtc *crtc)
struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc);
drm_crtc_cleanup(crtc);
+ qxl_bo_unref(&qxl_crtc->cursor_bo);
kfree(qxl_crtc);
}
@@ -296,6 +297,52 @@ qxl_hide_cursor(struct qxl_device *qdev)
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,
struct drm_file *file_priv,
uint32_t handle,
@@ -400,7 +447,8 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc,
}
drm_gem_object_unreference_unlocked(obj);
- qxl_bo_unref(&cursor_bo);
+ qxl_bo_unref (&qcrtc->cursor_bo);
+ qcrtc->cursor_bo = cursor_bo;
return ret;
@@ -655,6 +703,12 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc,
bo->surf.stride, bo->surf.format);
qxl_io_create_primary(qdev, 0, bo);
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) {
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 8e633caa4078..5f3e5ad99de7 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -137,6 +137,7 @@ struct qxl_crtc {
int cur_y;
int hot_spot_x;
int hot_spot_y;
+ struct qxl_bo *cursor_bo;
};
struct qxl_output {
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index b18ef3111f0c..06ad9238044e 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -75,6 +75,7 @@ typedef void (*virtio_gpu_resp_cb)(struct virtio_gpu_device *vgdev,
struct virtio_gpu_fence_driver {
atomic64_t last_seq;
uint64_t sync_seq;
+ uint64_t context;
struct list_head fences;
spinlock_t lock;
};
diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c
index cf4418709e76..f3f70fa8a4c7 100644
--- a/drivers/gpu/drm/virtio/virtgpu_fence.c
+++ b/drivers/gpu/drm/virtio/virtgpu_fence.c
@@ -89,7 +89,7 @@ int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
(*fence)->drv = drv;
(*fence)->seq = ++drv->sync_seq;
fence_init(&(*fence)->f, &virtio_fence_ops, &drv->lock,
- 0, (*fence)->seq);
+ drv->context, (*fence)->seq);
fence_get(&(*fence)->f);
list_add_tail(&(*fence)->node, &drv->fences);
spin_unlock_irqrestore(&drv->lock, irq_flags);
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 512e7cddcbae..818478b4c4f0 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -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_virtgpu_execbuffer *exbuf = data;
struct virtio_gpu_device *vgdev = dev->dev_private;
struct virtio_gpu_fpriv *vfpriv = drm_file->driver_priv;
struct drm_gem_object *gobj;
@@ -177,20 +183,6 @@ out_free:
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,
struct drm_file *file_priv)
{
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
index 4150873d432e..036b0fbae0fb 100644
--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
+++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
@@ -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->cursorq, virtio_gpu_dequeue_cursor_func);
+ vgdev->fence_drv.context = fence_context_alloc(1);
spin_lock_init(&vgdev->fence_drv.lock);
INIT_LIST_HEAD(&vgdev->fence_drv.fences);
INIT_LIST_HEAD(&vgdev->cap_cache);
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index 925ca25209df..ba28c0f6f28a 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -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);
if (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) {
vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
@@ -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);
if (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) {
vgfb = to_virtio_gpu_framebuffer(plane->state->fb);