bugfixes for qemu (bochs, qxl and virtio-gpu) drm drivers
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJX4lTNAAoJEEy22O7T6HE4aT4P/iWFkmG/Wg5WqANDrfZw6tPb sy7Nhl9w5L9tyMQY2Mvan3zaBEnpy/QVHCNn3iFBx68TeP6jO4eA5X4xtTGlFVV0 +K2vjPj7pYZKo4InwvTAnL9G5FpfPMtFydLsjuZOLwrfeAIDj3MMTpkvKiOAPkAg gNSmNGkt+rxo0gFVHyev1/TXjV5J2fXhv+NZiqdegEkdSFi7A63TO9pN0d/VDcCh c6ZoVy1OFKfTD/2kvtBqgeFghXThjkJv+38uRzZwq5yGerq/4L8FU5tD6WTAowzo MayJdGIKaSqEDMzIVVMkeCDcDGXrZNAJhwfw5LDsNU2M50LL2oRxil3t7PxLeG8l 9KOp3jR1L8LGpqyTZQBKrrWhFwF4iZ1f6U7Q3N2MSH8oGc7orqvklis23jhNNkk/ /oNBckGrX3Hof7mMgaug1RDjEfhXD82awhvEoQS7ep+jYhJnnfqvbx/GvTBc5i3t cXu1jNvh1tBKbdbEoFOBrNDla05IL5qD3LaPaH0w4un6YjUhEYdQliDz20e6N5uz R2f5BmqcHKkQHH108dOAUNgF9LiHqlZQPVyOYds8ACQTm874COPbgpyFohAl96Ri /swEXv8mijluOMp5ZCXaClNvsv18iW/eCNw2ohT8qWbPj4TTuJUy8Rx4RIFBEBMo /LoiT6Sf9UFljafQYt50 =lhHU -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
c0d5fb4d0d
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue