From: "Denis V. Lunev" <den@openvz.org>
To: qemu-devel@nongnu.org
Cc: den@openvz.org, qemu-stable@nongnu.org,
"Marc-André Lureau" <marcandre.lureau@redhat.com>
Subject: [PATCH 1/2] hw/display/qxl: hold ssd.lock while replacing ssd.cursor
Date: Thu, 3 Sep 2026 21:26:46 +0200 [thread overview]
Message-ID: <20260903192647.2677279-2-den@openvz.org> (raw)
In-Reply-To: <20260903192647.2677279-1-den@openvz.org>
From: Denis V. Lunev <den@openvz.org>
qxl_spice_reset_cursor() unrefs qxl->ssd.cursor and installs the hidden
cursor without holding qxl->ssd.lock. Every other writer of that field
takes it: qxl_render_cursor(), display_mouse_define() and
qemu_spice_cursor_refresh_bh().
The unlocked path runs on a vCPU thread, reached from ioport_write() on
QXL_IO_DESTROY_PRIMARY and QXL_IO_DESTROY_PRIMARY_ASYNC, and holds only
the BQL, which the SPICE display worker never takes. Unlike
qxl_hard_reset(), it leaves that worker running.
spice_qxl_reset_cursor() does round trip through the dispatcher, but the
worker is free again as soon as it returns, so it can enter
qxl_render_cursor() and unref the same QEMUCursor a few instructions
later. Both threads then drop one reference for what is a single
reference, freeing a cursor that another user still holds. The store to
ssd.cursor races the same way, and a guest that keeps this up also ends
up waiting forever in qxl_fence_wait().
A guest reaches this by switching QXL mode while it also updates the
pointer shape.
Fixes: 958c2bceba06 ("qxl: fix cursor reset")
Cc: qemu-stable@nongnu.org
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
---
hw/display/qxl.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 384b8767b8..c4f547e88b 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -294,10 +294,12 @@ void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
qemu_mutex_lock(&qxl->track_lock);
qxl->guest_cursor = 0;
qemu_mutex_unlock(&qxl->track_lock);
+ qemu_mutex_lock(&qxl->ssd.lock);
if (qxl->ssd.cursor) {
cursor_unref(qxl->ssd.cursor);
}
qxl->ssd.cursor = cursor_builtin_hidden();
+ qemu_mutex_unlock(&qxl->ssd.lock);
}
static uint32_t qxl_crc32(const uint8_t *p, unsigned len)
--
2.53.0
next prev parent reply other threads:[~2026-09-03 19:27 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-03 19:26 [PATCH 0/2] ui/cursor: fix two races that free a cursor early Denis V. Lunev
2026-09-03 19:26 ` Denis V. Lunev [this message]
2026-09-03 19:30 ` [PATCH 1/2] hw/display/qxl: hold ssd.lock while replacing ssd.cursor Marc-André Lureau
2026-09-03 19:26 ` [PATCH 2/2] ui/cursor: make the cursor refcount atomic Denis V. Lunev
2026-09-03 19:29 ` Marc-André Lureau
2026-09-13 19:57 ` [PATCH 0/2] ui/cursor: fix two races that free a cursor early Denis V. Lunev
2026-09-14 6:23 ` Marc-André Lureau
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260903192647.2677279-2-den@openvz.org \
--to=den@openvz.org \
--cc=marcandre.lureau@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-stable@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.