peterdelevoryas / rpms / qemu

Forked from rpms/qemu 2 years ago
Clone

Blame 0405-qxl-set-only-off-screen-surfaces-dirty-instead-of-th.patch

56753f
From 0386bf2be16745ce87f35ce65153ef4e11f93b22 Mon Sep 17 00:00:00 2001
56753f
From: Yonit Halperin <yhalperi@redhat.com>
56753f
Date: Wed, 15 Feb 2012 11:22:15 +0200
56753f
Subject: [PATCH 405/434] qxl: set only off-screen surfaces dirty instead of
56753f
 the whole vram
56753f
56753f
We used to assure the guest surfaces were saved before migration by
56753f
setting the whole vram dirty. This patch sets dirty only the areas
56753f
that are actually used in the vram.
56753f
56753f
Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
56753f
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
56753f
---
56753f
 hw/qxl.c |   53 ++++++++++++++++++++++++++++++++++++++++++++---------
56753f
 1 file changed, 44 insertions(+), 9 deletions(-)
56753f
56753f
diff --git a/hw/qxl.c b/hw/qxl.c
56753f
index 4fd5e4e..3d9b1b3 100644
56753f
--- a/hw/qxl.c
56753f
+++ b/hw/qxl.c
56753f
@@ -1010,7 +1010,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
56753f
     qxl_spice_destroy_surfaces(d, QXL_SYNC);
56753f
 }
56753f
 
56753f
-/* called from spice server thread context only */
56753f
+/* can be also called from spice server thread context */
56753f
 void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
56753f
 {
56753f
     uint64_t phys   = le64_to_cpu(pqxl);
56753f
@@ -1469,6 +1469,46 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
56753f
     }
56753f
 }
56753f
 
56753f
+static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
56753f
+{
56753f
+    intptr_t vram_start;
56753f
+    int i;
56753f
+
56753f
+    if (qxl->mode != QXL_MODE_NATIVE) {
56753f
+        return;
56753f
+    }
56753f
+
56753f
+    /* dirty the primary surface */
56753f
+    qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
56753f
+                  qxl->shadow_rom.surface0_area_size);
56753f
+
56753f
+    vram_start =  (intptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
56753f
+
56753f
+    /* dirty the off-screen surfaces */
56753f
+    for (i = 0; i < NUM_SURFACES; i++) {
56753f
+        QXLSurfaceCmd *cmd;
56753f
+        intptr_t surface_offset;
56753f
+        int surface_size;
56753f
+
56753f
+        if (qxl->guest_surfaces.cmds[i] == 0) {
56753f
+            continue;
56753f
+        }
56753f
+
56753f
+        cmd = qxl_phys2virt(qxl, qxl->guest_surfaces.cmds[i],
56753f
+                            MEMSLOT_GROUP_GUEST);
56753f
+        assert(cmd->type == QXL_SURFACE_CMD_CREATE);
56753f
+        surface_offset = (intptr_t)qxl_phys2virt(qxl,
56753f
+                                                 cmd->u.surface_create.data,
56753f
+                                                 MEMSLOT_GROUP_GUEST);
56753f
+        surface_offset -= vram_start;
56753f
+        surface_size = cmd->u.surface_create.height *
56753f
+                       abs(cmd->u.surface_create.stride);
56753f
+        dprint(qxl, 3, "%s: dirty surface %d, offset %d, size %d\n", __func__,
56753f
+               i, (int)surface_offset, surface_size);
56753f
+        qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);
56753f
+    }
56753f
+}
56753f
+
56753f
 static void qxl_vm_change_state_handler(void *opaque, int running,
56753f
                                         RunState state)
56753f
 {
56753f
@@ -1482,14 +1522,9 @@ static void qxl_vm_change_state_handler(void *opaque, int running,
56753f
          * called
56753f
          */
56753f
          qxl_update_irq(qxl);
56753f
-    } else if (qxl->mode == QXL_MODE_NATIVE) {
56753f
-        /* dirty all vram (which holds surfaces) and devram (primary surface)
56753f
-         * to make sure they are saved */
56753f
-        /* FIXME #1: should go out during "live" stage */
56753f
-        /* FIXME #2: we only need to save the areas which are actually used */
56753f
-        qxl_set_dirty(&qxl->vram_bar, 0, qxl->vram_size);
56753f
-        qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
56753f
-                      qxl->shadow_rom.surface0_area_size);
56753f
+    } else {
56753f
+        /* make sure surfaces are saved before migration */
56753f
+        qxl_dirty_surfaces(qxl);
56753f
     }
56753f
 }
56753f
 
56753f
-- 
56753f
1.7.10
56753f