summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Fergeau <cfergeau@redhat.com>2018-11-20 17:20:04 +0100
committerGerd Hoffmann <kraxel@redhat.com>2018-11-21 09:12:46 +0100
commit0081cdfe63f0b5e72b14d13f45a93ca7b0b8092f (patch)
tree6cff11e8bce594f84bf9ff9ff4bacf720e4abdee
parent545592fb3ddbf762001f3fa59f1464f73c3c3360 (diff)
qxl: Make sure qxl_cursor memory is pinneddrm-misc-next-2018-11-21
QEMU keeps a vram reference to the last QXLCursorCmd it received. This QXLCursorCmd command points to a QXLCursor instance (stored in vram too). However, while the QXLCursorCmd memory is pinned, the QXLCursor memory is not. When booting a recent Fedora to its login screen while monitoring the QXLCursorCmd QEMU holds, it's possible to see the QXLCursor memory becoming invalid shortly after boot. Pinning that memory ensures that that QXLCursor memory is not going to be moved by the guest kernel. Moving the pin/unpin to qxl_release_list_add()/qxl_release_free_list() would be a more generic fix. However, doing this quickly exhausts QXL video memory, so more fixing would be needed before this is workable. Signed-off-by: Christophe Fergeau <cfergeau@redhat.com> Link: http://patchwork.freedesktop.org/patch/msgid/20181120162004.22807-3-cfergeau@redhat.com Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index fc9f63cab548..ce0b9c40fc21 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -622,10 +622,14 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane,
if (ret)
goto out_kunmap;
- ret = qxl_release_reserve_list(release, true);
+ ret = qxl_bo_pin(cursor_bo);
if (ret)
goto out_free_bo;
+ ret = qxl_release_reserve_list(release, true);
+ if (ret)
+ goto out_unpin;
+
ret = qxl_bo_kmap(cursor_bo, (void **)&cursor);
if (ret)
goto out_backoff;
@@ -670,6 +674,8 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane,
qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
qxl_release_fence_buffer_objects(release);
+ if (old_cursor_bo != NULL)
+ qxl_bo_unpin(old_cursor_bo);
qxl_bo_unref(&old_cursor_bo);
qxl_bo_unref(&cursor_bo);
@@ -677,6 +683,8 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane,
out_backoff:
qxl_release_backoff_reserve_list(release);
+out_unpin:
+ qxl_bo_unpin(cursor_bo);
out_free_bo:
qxl_bo_unref(&cursor_bo);
out_kunmap: