Blame 0031-qxl-savevm-fixes.patch

Justin M. Forbes a81953
From e55e5fd43113a5b266efa6d17e44f0e9231a98ed Mon Sep 17 00:00:00 2001
Justin M. Forbes a81953
From: Gerd Hoffmann <kraxel@redhat.com>
Justin M. Forbes a81953
Date: Wed, 25 Aug 2010 16:08:37 +0000
Justin M. Forbes a81953
Subject: [PATCH 31/39] qxl: savevm fixes
Justin M. Forbes a81953
Justin M. Forbes a81953
---
Justin M. Forbes a81953
 hw/qxl.c |  125 +++++++++++++++++++++++++++++++++++++++++++++----------------
Justin M. Forbes a81953
 hw/qxl.h |    6 +++
Justin M. Forbes a81953
 2 files changed, 98 insertions(+), 33 deletions(-)
Justin M. Forbes a81953
Justin M. Forbes a81953
diff --git a/hw/qxl.c b/hw/qxl.c
Justin M. Forbes a81953
index 86c0e03..4a15200 100644
Justin M. Forbes a81953
--- a/hw/qxl.c
Justin M. Forbes a81953
+++ b/hw/qxl.c
Justin M. Forbes a81953
@@ -1087,6 +1087,14 @@ static void qxl_vm_change_state_handler(void *opaque, int running, int reason)
Justin M. Forbes a81953
 {
Justin M. Forbes a81953
     PCIQXLDevice *qxl = opaque;
Justin M. Forbes a81953
     qemu_spice_vm_change_state_handler(&qxl->ssd, running, reason);
Justin M. Forbes a81953
+
Justin M. Forbes a81953
+    if (!running && qxl->mode == QXL_MODE_NATIVE) {
Justin M. Forbes a81953
+        /* dirty all vram (which holds surfaces) to make sure it is saved */
Justin M. Forbes a81953
+        /* FIXME #1: should go out during "live" stage */
Justin M. Forbes a81953
+        /* FIXME #2: we only need to save the areas which are actually used */
Justin M. Forbes a81953
+        ram_addr_t addr = qxl->vram_offset;
Justin M. Forbes a81953
+        qxl_set_dirty(addr, addr + qxl->vram_size);
Justin M. Forbes a81953
+    }
Justin M. Forbes a81953
 }
Justin M. Forbes a81953
Justin M. Forbes a81953
 /* display change listener */
Justin M. Forbes a81953
@@ -1134,6 +1142,8 @@ static int qxl_init(PCIDevice *dev)
Justin M. Forbes a81953
     qxl->id = device_id;
Justin M. Forbes a81953
     qxl->mode = QXL_MODE_UNDEFINED;
Justin M. Forbes a81953
     qxl->generation = 1;
Justin M. Forbes a81953
+    qxl->num_memslots = NUM_MEMSLOTS;
Justin M. Forbes a81953
+    qxl->num_surfaces = NUM_SURFACES;
Justin M. Forbes a81953
Justin M. Forbes a81953
     switch (qxl->revision) {
Justin M. Forbes a81953
     case 1: /* spice 0.4 -- qxl-1 */
Justin M. Forbes a81953
@@ -1183,7 +1193,8 @@ static int qxl_init(PCIDevice *dev)
Justin M. Forbes a81953
         if (ram_size < 16 * 1024 * 1024)
Justin M. Forbes a81953
             ram_size = 16 * 1024 * 1024;
Justin M. Forbes a81953
         qxl->vga.vram_size = ram_size;
Justin M. Forbes a81953
-        qxl->vga.vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "bar0", qxl->vga.vram_size);
Justin M. Forbes a81953
+        qxl->vga.vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vgavram",
Justin M. Forbes a81953
+                                              qxl->vga.vram_size);
Justin M. Forbes a81953
         qxl->vga.vram_ptr = qemu_get_ram_ptr(qxl->vga.vram_offset);
Justin M. Forbes a81953
Justin M. Forbes a81953
         pci_config_set_class(config, PCI_CLASS_DISPLAY_OTHER);
Justin M. Forbes a81953
@@ -1195,14 +1206,14 @@ static int qxl_init(PCIDevice *dev)
Justin M. Forbes a81953
     pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
Justin M. Forbes a81953
Justin M. Forbes a81953
     qxl->rom_size = qxl_rom_size();
Justin M. Forbes a81953
-    qxl->rom_offset = qemu_ram_alloc(&qxl->pci.qdev, "bar2", qxl->rom_size);
Justin M. Forbes a81953
+    qxl->rom_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vrom", qxl->rom_size);
Justin M. Forbes a81953
     init_qxl_rom(qxl);
Justin M. Forbes a81953
     init_qxl_ram(qxl);
Justin M. Forbes a81953
Justin M. Forbes a81953
     if (qxl->vram_size < 16 * 1024 * 1024)
Justin M. Forbes a81953
         qxl->vram_size = 16 * 1024 * 1024;
Justin M. Forbes a81953
     qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
Justin M. Forbes a81953
-    qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "bar1", qxl->vram_size);
Justin M. Forbes a81953
+    qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vram", qxl->vram_size);
Justin M. Forbes a81953
Justin M. Forbes a81953
     pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX,
Justin M. Forbes a81953
                      msb_mask(QXL_IO_RANGE_SIZE * 2 - 1),
Justin M. Forbes a81953
@@ -1237,14 +1248,12 @@ static void qxl_pre_save(void *opaque)
Justin M. Forbes a81953
     uint8_t *ram_start = d->vga.vram_ptr;
Justin M. Forbes a81953
Justin M. Forbes a81953
     dprintf(d, 1, "%s:\n", __FUNCTION__);
Justin M. Forbes a81953
-#if 1 /* wanna zap this */
Justin M. Forbes a81953
     if (d->last_release == NULL) {
Justin M. Forbes a81953
         d->last_release_offset = 0;
Justin M. Forbes a81953
     } else {
Justin M. Forbes a81953
         d->last_release_offset = (uint8_t *)d->last_release - ram_start;
Justin M. Forbes a81953
     }
Justin M. Forbes a81953
     assert(d->last_release_offset < d->vga.vram_size);
Justin M. Forbes a81953
-#endif
Justin M. Forbes a81953
 }
Justin M. Forbes a81953
Justin M. Forbes a81953
 static int qxl_pre_load(void *opaque)
Justin M. Forbes a81953
@@ -1306,29 +1315,55 @@ static int qxl_post_load(void *opaque, int version)
Justin M. Forbes a81953
     }
Justin M. Forbes a81953
     dprintf(d, 1, "%s: done\n", __FUNCTION__);
Justin M. Forbes a81953
Justin M. Forbes a81953
-#if 1 /* wanna zap this */
Justin M. Forbes a81953
-    if (d->last_release_offset >= d->vga.vram_size) {
Justin M. Forbes a81953
-        dprintf(d, 1, "%s: invalid last_release_offset %u, ram_size %u\n",
Justin M. Forbes a81953
-                __FUNCTION__, d->last_release_offset, d->vga.vram_size);
Justin M. Forbes a81953
-        exit(-1);
Justin M. Forbes a81953
-    }
Justin M. Forbes a81953
-
Justin M. Forbes a81953
+    assert(d->last_release_offset < d->vga.vram_size);
Justin M. Forbes a81953
     if (d->last_release_offset == 0) {
Justin M. Forbes a81953
         d->last_release = NULL;
Justin M. Forbes a81953
     } else {
Justin M. Forbes a81953
         d->last_release = (QXLReleaseInfo *)(ram_start + d->last_release_offset);
Justin M. Forbes a81953
     }
Justin M. Forbes a81953
-#endif
Justin M. Forbes a81953
+
Justin M. Forbes a81953
+    /* spice 0.4 compatibility -- accept but ignore */
Justin M. Forbes a81953
+    free(d->worker_data);
Justin M. Forbes a81953
+    d->worker_data = NULL;
Justin M. Forbes a81953
+    d->worker_data_size = 0;
Justin M. Forbes a81953
Justin M. Forbes a81953
     return 0;
Justin M. Forbes a81953
 }
Justin M. Forbes a81953
Justin M. Forbes a81953
-#define QXL_VER 1
Justin M. Forbes a81953
+#define QXL_SAVE_VERSION 20
Justin M. Forbes a81953
+
Justin M. Forbes a81953
+static bool qxl_test_worker_data(void *opaque, int version_id)
Justin M. Forbes a81953
+{
Justin M. Forbes a81953
+    PCIQXLDevice* d = opaque;
Justin M. Forbes a81953
+
Justin M. Forbes a81953
+    if (d->revision != 1) {
Justin M. Forbes a81953
+        return false;
Justin M. Forbes a81953
+    }
Justin M. Forbes a81953
+    if (!d->worker_data_size) {
Justin M. Forbes a81953
+        return false;
Justin M. Forbes a81953
+    }
Justin M. Forbes a81953
+    if (!d->worker_data) {
Justin M. Forbes a81953
+        d->worker_data = qemu_malloc(d->worker_data_size);
Justin M. Forbes a81953
+    }
Justin M. Forbes a81953
+    return true;
Justin M. Forbes a81953
+}
Justin M. Forbes a81953
+
Justin M. Forbes a81953
+static bool qxl_test_spice04(void *opaque, int version_id)
Justin M. Forbes a81953
+{
Justin M. Forbes a81953
+    PCIQXLDevice* d = opaque;
Justin M. Forbes a81953
+    return d->revision == 1;
Justin M. Forbes a81953
+}
Justin M. Forbes a81953
+
Justin M. Forbes a81953
+static bool qxl_test_spice06(void *opaque)
Justin M. Forbes a81953
+{
Justin M. Forbes a81953
+    PCIQXLDevice* d = opaque;
Justin M. Forbes a81953
+    return d->revision > 1;
Justin M. Forbes a81953
+}
Justin M. Forbes a81953
Justin M. Forbes a81953
 static VMStateDescription qxl_memslot = {
Justin M. Forbes a81953
     .name               = "qxl-memslot",
Justin M. Forbes a81953
-    .version_id         = QXL_VER,
Justin M. Forbes a81953
-    .minimum_version_id = QXL_VER,
Justin M. Forbes a81953
+    .version_id         = QXL_SAVE_VERSION,
Justin M. Forbes a81953
+    .minimum_version_id = QXL_SAVE_VERSION,
Justin M. Forbes a81953
     .fields = (VMStateField[]) {
Justin M. Forbes a81953
         VMSTATE_UINT64(slot.mem_start, struct guest_slots),
Justin M. Forbes a81953
         VMSTATE_UINT64(slot.mem_end,   struct guest_slots),
Justin M. Forbes a81953
@@ -1339,8 +1374,8 @@ static VMStateDescription qxl_memslot = {
Justin M. Forbes a81953
Justin M. Forbes a81953
 static VMStateDescription qxl_surface = {
Justin M. Forbes a81953
     .name               = "qxl-surface",
Justin M. Forbes a81953
-    .version_id         = QXL_VER,
Justin M. Forbes a81953
-    .minimum_version_id = QXL_VER,
Justin M. Forbes a81953
+    .version_id         = QXL_SAVE_VERSION,
Justin M. Forbes a81953
+    .minimum_version_id = QXL_SAVE_VERSION,
Justin M. Forbes a81953
     .fields = (VMStateField[]) {
Justin M. Forbes a81953
         VMSTATE_UINT32(width,      QXLSurfaceCreate),
Justin M. Forbes a81953
         VMSTATE_UINT32(height,     QXLSurfaceCreate),
Justin M. Forbes a81953
@@ -1355,34 +1390,58 @@ static VMStateDescription qxl_surface = {
Justin M. Forbes a81953
     }
Justin M. Forbes a81953
 };
Justin M. Forbes a81953
Justin M. Forbes a81953
+static VMStateDescription qxl_vmstate_spice06 = {
Justin M. Forbes a81953
+    .name               = "qxl/spice06",
Justin M. Forbes a81953
+    .version_id         = QXL_SAVE_VERSION,
Justin M. Forbes a81953
+    .minimum_version_id = QXL_SAVE_VERSION,
Justin M. Forbes a81953
+    .fields = (VMStateField []) {
Justin M. Forbes a81953
+        VMSTATE_INT32_EQUAL(num_memslots, PCIQXLDevice),
Justin M. Forbes a81953
+        VMSTATE_STRUCT_ARRAY(guest_slots, PCIQXLDevice, NUM_MEMSLOTS, 0,
Justin M. Forbes a81953
+                             qxl_memslot, struct guest_slots),
Justin M. Forbes a81953
+        VMSTATE_STRUCT(guest_primary.surface, PCIQXLDevice, 0,
Justin M. Forbes a81953
+                       qxl_surface, QXLSurfaceCreate),
Justin M. Forbes a81953
+        VMSTATE_INT32_EQUAL(num_surfaces, PCIQXLDevice),
Justin M. Forbes a81953
+        VMSTATE_ARRAY(guest_surfaces.cmds, PCIQXLDevice, NUM_SURFACES, 0,
Justin M. Forbes a81953
+                      vmstate_info_uint64, uint64_t),
Justin M. Forbes a81953
+        VMSTATE_UINT64(guest_cursor, PCIQXLDevice),
Justin M. Forbes a81953
+        VMSTATE_END_OF_LIST()
Justin M. Forbes a81953
+    },
Justin M. Forbes a81953
+};
Justin M. Forbes a81953
+
Justin M. Forbes a81953
 static VMStateDescription qxl_vmstate = {
Justin M. Forbes a81953
     .name               = "qxl",
Justin M. Forbes a81953
-    .version_id         = QXL_VER,
Justin M. Forbes a81953
-    .minimum_version_id = QXL_VER,
Justin M. Forbes a81953
+    .version_id         = QXL_SAVE_VERSION,
Justin M. Forbes a81953
+    .minimum_version_id = QXL_SAVE_VERSION,
Justin M. Forbes a81953
     .pre_save           = qxl_pre_save,
Justin M. Forbes a81953
     .pre_load           = qxl_pre_load,
Justin M. Forbes a81953
     .post_load          = qxl_post_load,
Justin M. Forbes a81953
     .fields = (VMStateField []) {
Justin M. Forbes a81953
         VMSTATE_PCI_DEVICE(pci, PCIQXLDevice),
Justin M. Forbes a81953
-        VMSTATE_STRUCT(vga, PCIQXLDevice, QXL_VER, vmstate_vga_common, VGACommonState),
Justin M. Forbes a81953
+        VMSTATE_STRUCT(vga, PCIQXLDevice, 0, vmstate_vga_common, VGACommonState),
Justin M. Forbes a81953
         VMSTATE_UINT32(shadow_rom.mode, PCIQXLDevice),
Justin M. Forbes a81953
-#if 1 /* wanna zap this */
Justin M. Forbes a81953
         VMSTATE_UINT32(num_free_res, PCIQXLDevice),
Justin M. Forbes a81953
         VMSTATE_UINT32(last_release_offset, PCIQXLDevice),
Justin M. Forbes a81953
-#endif
Justin M. Forbes a81953
         VMSTATE_UINT32(mode, PCIQXLDevice),
Justin M. Forbes a81953
         VMSTATE_UINT32(ssd.unique, PCIQXLDevice),
Justin M. Forbes a81953
-#if 1 /* new stuff */
Justin M. Forbes a81953
-        VMSTATE_STRUCT_ARRAY(guest_slots, PCIQXLDevice, NUM_MEMSLOTS, QXL_VER,
Justin M. Forbes a81953
-                             qxl_memslot, struct guest_slots),
Justin M. Forbes a81953
-        VMSTATE_STRUCT(guest_primary.surface, PCIQXLDevice, QXL_VER,
Justin M. Forbes a81953
-                       qxl_surface, QXLSurfaceCreate),
Justin M. Forbes a81953
-        VMSTATE_ARRAY(guest_surfaces.cmds, PCIQXLDevice, NUM_SURFACES, QXL_VER,
Justin M. Forbes a81953
-                      vmstate_info_uint64, uint64_t),
Justin M. Forbes a81953
-        VMSTATE_UINT64(guest_cursor, PCIQXLDevice),
Justin M. Forbes a81953
-#endif
Justin M. Forbes a81953
+
Justin M. Forbes a81953
+        /* spice 0.4 sends/expects them */
Justin M. Forbes a81953
+        VMSTATE_VBUFFER_UINT32(vga.vram_ptr, PCIQXLDevice, 0, qxl_test_spice04, 0,
Justin M. Forbes a81953
+                               vga.vram_size),
Justin M. Forbes a81953
+        VMSTATE_UINT32_TEST(worker_data_size, PCIQXLDevice, qxl_test_spice04),
Justin M. Forbes a81953
+        VMSTATE_VBUFFER_UINT32(worker_data, PCIQXLDevice, 0, qxl_test_worker_data, 0,
Justin M. Forbes a81953
+                               worker_data_size),
Justin M. Forbes a81953
+
Justin M. Forbes a81953
         VMSTATE_END_OF_LIST()
Justin M. Forbes a81953
-    }
Justin M. Forbes a81953
+    },
Justin M. Forbes a81953
+    .subsections = (VMStateSubsection[]) {
Justin M. Forbes a81953
+        {
Justin M. Forbes a81953
+            /* additional spice 0.6 state */
Justin M. Forbes a81953
+            .vmsd   = &qxl_vmstate_spice06,
Justin M. Forbes a81953
+            .needed = qxl_test_spice06,
Justin M. Forbes a81953
+        },{
Justin M. Forbes a81953
+            /* end of list */
Justin M. Forbes a81953
+        },
Justin M. Forbes a81953
+    },
Justin M. Forbes a81953
 };
Justin M. Forbes a81953
Justin M. Forbes a81953
 static PCIDeviceInfo qxl_info = {
Justin M. Forbes a81953
diff --git a/hw/qxl.h b/hw/qxl.h
Justin M. Forbes a81953
index 1216405..caf3684 100644
Justin M. Forbes a81953
--- a/hw/qxl.h
Justin M. Forbes a81953
+++ b/hw/qxl.h
Justin M. Forbes a81953
@@ -24,6 +24,9 @@ typedef struct PCIQXLDevice {
Justin M. Forbes a81953
     int                generation;
Justin M. Forbes a81953
     uint32_t           revision;
Justin M. Forbes a81953
Justin M. Forbes a81953
+    int32_t            num_memslots;
Justin M. Forbes a81953
+    int32_t            num_surfaces;
Justin M. Forbes a81953
+
Justin M. Forbes a81953
     struct guest_slots {
Justin M. Forbes a81953
         QXLMemSlot     slot;
Justin M. Forbes a81953
         void           *ptr;
Justin M. Forbes a81953
@@ -74,6 +77,9 @@ typedef struct PCIQXLDevice {
Justin M. Forbes a81953
     /* io bar */
Justin M. Forbes a81953
     uint32_t           io_base;
Justin M. Forbes a81953
Justin M. Forbes a81953
+    /* spice 0.4 loadvm compatibility */
Justin M. Forbes a81953
+    void               *worker_data;
Justin M. Forbes a81953
+    uint32_t           worker_data_size;
Justin M. Forbes a81953
 } PCIQXLDevice;
Justin M. Forbes a81953
Justin M. Forbes a81953
 #define PANIC_ON(x) if ((x)) {                         \
Justin M. Forbes a81953
-- 
Justin M. Forbes a81953
1.7.2.3
Justin M. Forbes a81953