Commit 050f5408bf for qemu.org
commit 050f5408bfcff56a65aed6d9ab81e35f4ba82631
Author: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Date: Tue Aug 25 20:20:49 2026 +0300
hw/display/qxl: factor out qxl_guest_phys2virt()
Split the GROUP_GUEST half of qxl_phys2virt() into the helper
qxl_guest_phys2virt(). Also add a bool 'report_bug' param to the
qxl_get_check_slot_offset() called from it: when it's false, a failing
check just returns false without calling qxl_set_guest_bug(). All
existing callers pass true, so there's no functional change. This
is in preparation for a quiet caller that validates guest addresses
which might be legitimately stale, when flagging a guest bug would be
wrong.
Message-ID: <20260825172051.435372-2-andrey.drobyshev@virtuozzo.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index c4f547e88b..b6bc182fc2 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -1409,7 +1409,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
/* can be also called from spice server thread context */
static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
uint32_t *s, uint64_t *o,
- size_t size_requested)
+ size_t size_requested, bool report_bug)
{
uint64_t phys = le64_to_cpu(pqxl);
uint32_t slot = (phys >> (64 - 8)) & 0xff;
@@ -1417,42 +1417,55 @@ static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
uint64_t size_available;
if (slot >= NUM_MEMSLOTS) {
- qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot,
- NUM_MEMSLOTS);
+ if (report_bug) {
+ qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot,
+ NUM_MEMSLOTS);
+ }
return false;
}
if (!qxl->guest_slots[slot].active) {
- qxl_set_guest_bug(qxl, "inactive slot %d\n", slot);
+ if (report_bug) {
+ qxl_set_guest_bug(qxl, "inactive slot %d\n", slot);
+ }
return false;
}
if (offset < qxl->guest_slots[slot].delta) {
- qxl_set_guest_bug(qxl,
- "slot %d offset %"PRIu64" < delta %"PRIu64"\n",
- slot, offset, qxl->guest_slots[slot].delta);
+ if (report_bug) {
+ qxl_set_guest_bug(qxl,
+ "slot %d offset %"PRIu64" < delta %"PRIu64"\n",
+ slot, offset, qxl->guest_slots[slot].delta);
+ }
return false;
}
offset -= qxl->guest_slots[slot].delta;
if (offset > qxl->guest_slots[slot].size) {
- qxl_set_guest_bug(qxl,
- "slot %d offset %"PRIu64" > size %"PRIu64"\n",
- slot, offset, qxl->guest_slots[slot].size);
+ if (report_bug) {
+ qxl_set_guest_bug(qxl,
+ "slot %d offset %"PRIu64" > size %"PRIu64"\n",
+ slot, offset, qxl->guest_slots[slot].size);
+ }
return false;
}
size_available = memory_region_size(qxl->guest_slots[slot].mr);
if (qxl->guest_slots[slot].offset + offset >= size_available) {
- qxl_set_guest_bug(qxl,
- "slot %d offset %"PRIu64" > region size %"PRIu64"\n",
- slot, qxl->guest_slots[slot].offset + offset,
- size_available);
+ if (report_bug) {
+ qxl_set_guest_bug(qxl,
+ "slot %d offset %"PRIu64" > region size %"PRIu64
+ "\n", slot,
+ qxl->guest_slots[slot].offset + offset,
+ size_available);
+ }
return false;
}
size_available -= qxl->guest_slots[slot].offset + offset;
if (size_requested > size_available) {
- qxl_set_guest_bug(qxl,
- "slot %d offset %"PRIu64" size %zu: "
- "overrun by %"PRIu64" bytes\n",
- slot, offset, size_requested,
- size_requested - size_available);
+ if (report_bug) {
+ qxl_set_guest_bug(qxl,
+ "slot %d offset %"PRIu64" size %zu: "
+ "overrun by %"PRIu64" bytes\n",
+ slot, offset, size_requested,
+ size_requested - size_available);
+ }
return false;
}
@@ -1462,25 +1475,31 @@ static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
}
/* can be also called from spice server thread context */
-void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id,
- size_t size)
+static void *qxl_guest_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
+ size_t size, bool report_bug)
{
uint64_t offset;
uint32_t slot;
- void *ptr;
+ uint8_t *ptr;
+ if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size,
+ report_bug)) {
+ return NULL;
+ }
+ ptr = memory_region_get_ram_ptr(qxl->guest_slots[slot].mr);
+ ptr += qxl->guest_slots[slot].offset;
+ ptr += offset;
+ return ptr;
+}
+
+void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id,
+ size_t size)
+{
switch (group_id) {
case MEMSLOT_GROUP_HOST:
- offset = le64_to_cpu(pqxl) & 0xffffffffffff;
- return (void *)(intptr_t)offset;
+ return (void *)(intptr_t)(le64_to_cpu(pqxl) & 0xffffffffffff);
case MEMSLOT_GROUP_GUEST:
- if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size)) {
- return NULL;
- }
- ptr = memory_region_get_ram_ptr(qxl->guest_slots[slot].mr);
- ptr += qxl->guest_slots[slot].offset;
- ptr += offset;
- return ptr;
+ return qxl_guest_phys2virt(qxl, pqxl, size, true);
}
return NULL;
}
@@ -2003,7 +2022,7 @@ static void qxl_dirty_one_surface(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
bool rc;
size = (uint64_t)height * abs(stride);
- rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size);
+ rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size, true);
assert(rc == true);
trace_qxl_surfaces_dirty(qxl->id, offset, size);
qxl_set_dirty(qxl->guest_slots[slot].mr,