aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-09-27 23:23:07 -0400
committerDave Airlie <airlied@redhat.com>2016-09-27 23:23:07 -0400
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)
163static int bochs_pci_probe(struct pci_dev *pdev, 163static int bochs_pci_probe(struct pci_dev *pdev,
164 const struct pci_device_id *ent) 164 const struct pci_device_id *ent)
165{ 165{
166 unsigned long fbsize;
166 int ret; 167 int ret;
167 168
169 fbsize = pci_resource_len(pdev, 0);
170 if (fbsize < 4 * 1024 * 1024) {
171 DRM_ERROR("less than 4 MB video memory, ignoring device\n");
172 return -ENOMEM;
173 }
174
168 ret = bochs_kick_out_firmware_fb(pdev); 175 ret = bochs_kick_out_firmware_fb(pdev);
169 if (ret) 176 if (ret)
170 return ret; 177 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)
211 struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc); 211 struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc);
212 212
213 drm_crtc_cleanup(crtc); 213 drm_crtc_cleanup(crtc);
214 qxl_bo_unref(&qxl_crtc->cursor_bo);
214 kfree(qxl_crtc); 215 kfree(qxl_crtc);
215} 216}
216 217
@@ -296,6 +297,52 @@ qxl_hide_cursor(struct qxl_device *qdev)
296 return 0; 297 return 0;
297} 298}
298 299
300static int qxl_crtc_apply_cursor(struct drm_crtc *crtc)
301{
302 struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
303 struct drm_device *dev = crtc->dev;
304 struct qxl_device *qdev = dev->dev_private;
305 struct qxl_cursor_cmd *cmd;
306 struct qxl_release *release;
307 int ret = 0;
308
309 if (!qcrtc->cursor_bo)
310 return 0;
311
312 ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd),
313 QXL_RELEASE_CURSOR_CMD,
314 &release, NULL);
315 if (ret)
316 return ret;
317
318 ret = qxl_release_list_add(release, qcrtc->cursor_bo);
319 if (ret)
320 goto out_free_release;
321
322 ret = qxl_release_reserve_list(release, false);
323 if (ret)
324 goto out_free_release;
325
326 cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
327 cmd->type = QXL_CURSOR_SET;
328 cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x;
329 cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y;
330
331 cmd->u.set.shape = qxl_bo_physical_address(qdev, qcrtc->cursor_bo, 0);
332
333 cmd->u.set.visible = 1;
334 qxl_release_unmap(qdev, release, &cmd->release_info);
335
336 qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
337 qxl_release_fence_buffer_objects(release);
338
339 return ret;
340
341out_free_release:
342 qxl_release_free(qdev, release);
343 return ret;
344}
345
299static int qxl_crtc_cursor_set2(struct drm_crtc *crtc, 346static int qxl_crtc_cursor_set2(struct drm_crtc *crtc,
300 struct drm_file *file_priv, 347 struct drm_file *file_priv,
301 uint32_t handle, 348 uint32_t handle,
@@ -400,7 +447,8 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc,
400 } 447 }
401 drm_gem_object_unreference_unlocked(obj); 448 drm_gem_object_unreference_unlocked(obj);
402 449
403 qxl_bo_unref(&cursor_bo); 450 qxl_bo_unref (&qcrtc->cursor_bo);
451 qcrtc->cursor_bo = cursor_bo;
404 452
405 return ret; 453 return ret;
406 454
@@ -655,6 +703,12 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc,
655 bo->surf.stride, bo->surf.format); 703 bo->surf.stride, bo->surf.format);
656 qxl_io_create_primary(qdev, 0, bo); 704 qxl_io_create_primary(qdev, 0, bo);
657 bo->is_primary = true; 705 bo->is_primary = true;
706
707 ret = qxl_crtc_apply_cursor(crtc);
708 if (ret) {
709 DRM_ERROR("could not set cursor after modeset");
710 ret = 0;
711 }
658 } 712 }
659 713
660 if (bo->is_primary) { 714 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 {
137 int cur_y; 137 int cur_y;
138 int hot_spot_x; 138 int hot_spot_x;
139 int hot_spot_y; 139 int hot_spot_y;
140 struct qxl_bo *cursor_bo;
140}; 141};
141 142
142struct qxl_output { 143struct 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,
75struct virtio_gpu_fence_driver { 75struct virtio_gpu_fence_driver {
76 atomic64_t last_seq; 76 atomic64_t last_seq;
77 uint64_t sync_seq; 77 uint64_t sync_seq;
78 uint64_t context;
78 struct list_head fences; 79 struct list_head fences;
79 spinlock_t lock; 80 spinlock_t lock;
80}; 81};
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,
89 (*fence)->drv = drv; 89 (*fence)->drv = drv;
90 (*fence)->seq = ++drv->sync_seq; 90 (*fence)->seq = ++drv->sync_seq;
91 fence_init(&(*fence)->f, &virtio_fence_ops, &drv->lock, 91 fence_init(&(*fence)->f, &virtio_fence_ops, &drv->lock,
92 0, (*fence)->seq); 92 drv->context, (*fence)->seq);
93 fence_get(&(*fence)->f); 93 fence_get(&(*fence)->f);
94 list_add_tail(&(*fence)->node, &drv->fences); 94 list_add_tail(&(*fence)->node, &drv->fences);
95 spin_unlock_irqrestore(&drv->lock, irq_flags); 95 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)
89 } 89 }
90} 90}
91 91
92static int virtio_gpu_execbuffer(struct drm_device *dev, 92/*
93 struct drm_virtgpu_execbuffer *exbuf, 93 * Usage of execbuffer:
94 * Relocations need to take into account the full VIRTIO_GPUDrawable size.
95 * However, the command as passed from user space must *not* contain the initial
96 * VIRTIO_GPUReleaseInfo struct (first XXX bytes)
97 */
98static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
94 struct drm_file *drm_file) 99 struct drm_file *drm_file)
95{ 100{
101 struct drm_virtgpu_execbuffer *exbuf = data;
96 struct virtio_gpu_device *vgdev = dev->dev_private; 102 struct virtio_gpu_device *vgdev = dev->dev_private;
97 struct virtio_gpu_fpriv *vfpriv = drm_file->driver_priv; 103 struct virtio_gpu_fpriv *vfpriv = drm_file->driver_priv;
98 struct drm_gem_object *gobj; 104 struct drm_gem_object *gobj;
@@ -177,20 +183,6 @@ out_free:
177 return ret; 183 return ret;
178} 184}
179 185
180/*
181 * Usage of execbuffer:
182 * Relocations need to take into account the full VIRTIO_GPUDrawable size.
183 * However, the command as passed from user space must *not* contain the initial
184 * VIRTIO_GPUReleaseInfo struct (first XXX bytes)
185 */
186static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
187 struct drm_file *file_priv)
188{
189 struct drm_virtgpu_execbuffer *execbuffer = data;
190 return virtio_gpu_execbuffer(dev, execbuffer, file_priv);
191}
192
193
194static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data, 186static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data,
195 struct drm_file *file_priv) 187 struct drm_file *file_priv)
196{ 188{
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)
159 virtio_gpu_init_vq(&vgdev->ctrlq, virtio_gpu_dequeue_ctrl_func); 159 virtio_gpu_init_vq(&vgdev->ctrlq, virtio_gpu_dequeue_ctrl_func);
160 virtio_gpu_init_vq(&vgdev->cursorq, virtio_gpu_dequeue_cursor_func); 160 virtio_gpu_init_vq(&vgdev->cursorq, virtio_gpu_dequeue_cursor_func);
161 161
162 vgdev->fence_drv.context = fence_context_alloc(1);
162 spin_lock_init(&vgdev->fence_drv.lock); 163 spin_lock_init(&vgdev->fence_drv.lock);
163 INIT_LIST_HEAD(&vgdev->fence_drv.fences); 164 INIT_LIST_HEAD(&vgdev->fence_drv.fences);
164 INIT_LIST_HEAD(&vgdev->cap_cache); 165 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,
76 output = drm_crtc_to_virtio_gpu_output(plane->state->crtc); 76 output = drm_crtc_to_virtio_gpu_output(plane->state->crtc);
77 if (old_state->crtc) 77 if (old_state->crtc)
78 output = drm_crtc_to_virtio_gpu_output(old_state->crtc); 78 output = drm_crtc_to_virtio_gpu_output(old_state->crtc);
79 WARN_ON(!output); 79 if (WARN_ON(!output))
80 return;
80 81
81 if (plane->state->fb) { 82 if (plane->state->fb) {
82 vgfb = to_virtio_gpu_framebuffer(plane->state->fb); 83 vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
@@ -129,7 +130,8 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane,
129 output = drm_crtc_to_virtio_gpu_output(plane->state->crtc); 130 output = drm_crtc_to_virtio_gpu_output(plane->state->crtc);
130 if (old_state->crtc) 131 if (old_state->crtc)
131 output = drm_crtc_to_virtio_gpu_output(old_state->crtc); 132 output = drm_crtc_to_virtio_gpu_output(old_state->crtc);
132 WARN_ON(!output); 133 if (WARN_ON(!output))
134 return;
133 135
134 if (plane->state->fb) { 136 if (plane->state->fb) {
135 vgfb = to_virtio_gpu_framebuffer(plane->state->fb); 137 vgfb = to_virtio_gpu_framebuffer(plane->state->fb);