summaryrefslogtreecommitdiff
path: root/hw/qxl.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/qxl.c')
-rw-r--r--hw/qxl.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/hw/qxl.c b/hw/qxl.c
index 1f56fcd169..1bc2d32aa8 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -293,6 +293,10 @@ void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
qemu_mutex_lock(&qxl->track_lock);
qxl->guest_cursor = 0;
qemu_mutex_unlock(&qxl->track_lock);
+ if (qxl->ssd.cursor) {
+ cursor_put(qxl->ssd.cursor);
+ }
+ qxl->ssd.cursor = cursor_builtin_hidden();
}
@@ -447,6 +451,12 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
qxl->ssd.num_surfaces);
return 1;
}
+ if (cmd->type == QXL_SURFACE_CMD_CREATE &&
+ (cmd->u.surface_create.stride & 0x03) != 0) {
+ qxl_set_guest_bug(qxl, "QXL_CMD_SURFACE stride = %d %% 4 != 0\n",
+ cmd->u.surface_create.stride);
+ return 1;
+ }
qemu_mutex_lock(&qxl->track_lock);
if (cmd->type == QXL_SURFACE_CMD_CREATE) {
qxl->guest_surfaces.cmds[id] = ext->cmd.data;
@@ -1059,7 +1069,7 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d)
trace_qxl_enter_vga_mode(d->id);
qemu_spice_create_host_primary(&d->ssd);
d->mode = QXL_MODE_VGA;
- memset(&d->ssd.dirty, 0, sizeof(d->ssd.dirty));
+ dpy_gfx_resize(d->ssd.ds);
vga_dirty_log_start(&d->vga);
}
@@ -1357,6 +1367,12 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
trace_qxl_create_guest_primary_rest(qxl->id, sc->stride, sc->type,
sc->flags);
+ if ((surface.stride & 0x3) != 0) {
+ qxl_set_guest_bug(qxl, "primary surface stride = %d %% 4 != 0",
+ surface.stride);
+ return;
+ }
+
surface.mouse_mode = true;
surface.group_id = MEMSLOT_GROUP_GUEST;
if (loadvm) {
@@ -1689,7 +1705,13 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
uint32_t le_events = cpu_to_le32(events);
trace_qxl_send_events(d->id, events);
- assert(qemu_spice_display_is_running(&d->ssd));
+ if (!qemu_spice_display_is_running(&d->ssd)) {
+ /* spice-server tracks guest running state and should not do this */
+ fprintf(stderr, "%s: spice-server bug: guest stopped, ignoring\n",
+ __func__);
+ trace_qxl_send_events_vm_stopped(d->id, events);
+ return;
+ }
old_pending = __sync_fetch_and_or(&d->ram->int_pending, le_events);
if ((old_pending & le_events) == le_events) {
return;
@@ -2027,6 +2049,7 @@ static int qxl_init_primary(PCIDevice *dev)
PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
VGACommonState *vga = &qxl->vga;
PortioList *qxl_vga_port_list = g_new(PortioList, 1);
+ int rc;
qxl->id = 0;
qxl_init_ramsize(qxl);
@@ -2041,9 +2064,14 @@ static int qxl_init_primary(PCIDevice *dev)
qemu_spice_display_init_common(&qxl->ssd, vga->ds);
qxl0 = qxl;
- register_displaychangelistener(vga->ds, &display_listener);
- return qxl_init_common(qxl);
+ rc = qxl_init_common(qxl);
+ if (rc != 0) {
+ return rc;
+ }
+
+ register_displaychangelistener(vga->ds, &display_listener);
+ return rc;
}
static int qxl_init_secondary(PCIDevice *dev)