diff options
author | Dave Airlie <airlied@redhat.com> | 2016-09-27 23:23:07 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-09-27 23:23:07 -0400 |
commit | c0d5fb4d0d9224ccaad0475c9b58740873970e7e (patch) | |
tree | 202ee565e7d873f6580b85251aba75a00bac1fc2 | |
parent | ca09fb9f60b5f3ab2d57e761aaeea89a5147d784 (diff) | |
parent | 30b9c96cf7b44d53b9165649c8be34ac234be324 (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.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_display.c | 56 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_fence.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_ioctl.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_kms.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_plane.c | 6 |
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) | |||
163 | static int bochs_pci_probe(struct pci_dev *pdev, | 163 | static 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 | ||
300 | static 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 | |||
341 | out_free_release: | ||
342 | qxl_release_free(qdev, release); | ||
343 | return ret; | ||
344 | } | ||
345 | |||
299 | static int qxl_crtc_cursor_set2(struct drm_crtc *crtc, | 346 | static 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 | ||
142 | struct qxl_output { | 143 | 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, | |||
75 | struct virtio_gpu_fence_driver { | 75 | struct 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 | ||
92 | static 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 | */ | ||
98 | static 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 | */ | ||
186 | static 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 | |||
194 | static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data, | 186 | static 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); |