qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PULL 5/9] qxl: fix surface migration


From: Gerd Hoffmann
Subject: [Qemu-devel] [PULL 5/9] qxl: fix surface migration
Date: Wed, 6 Jul 2016 12:04:38 +0200

Create a helper function qxl_dirty_one_surface() to mark a single qxl
surface as dirty.  Use the new qxl_get_check_slot_offset function and
lookup the memory region from the slot instead of assuming the surface
is stored in vram.

Use the new helper function in qxl_dirty_surfaces, for both primary and
off-screen surfaces.  For off-screen surfaces this is no functional
change.  For primary surfaces this will dirty only the memory actually
used instead of the whole surface0 region.  It will also work correctly
in case the guest places the primary surface in vram instead of the
surface0 region (linux kms driver does that).

https://bugzilla.redhat.com/show_bug.cgi?id=1235732

Signed-off-by: Gerd Hoffmann <address@hidden>
Message-id: address@hidden
---
 hw/display/qxl.c        | 37 +++++++++++++++++++++----------------
 hw/display/trace-events |  2 +-
 2 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 8101f69..65a3653 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -1809,9 +1809,23 @@ static void qxl_hw_update(void *opaque)
     qxl_render_update(qxl);
 }
 
+static void qxl_dirty_one_surface(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
+                                  uint32_t height, int32_t stride)
+{
+    uint64_t offset;
+    uint32_t slot, size;
+    bool rc;
+
+    rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset);
+    assert(rc == true);
+    size = height * abs(stride);
+    trace_qxl_surfaces_dirty(qxl->id, (int)offset, size);
+    qxl_set_dirty(qxl->guest_slots[slot].mr,
+                  qxl->guest_slots[slot].offset + offset, size);
+}
+
 static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
 {
-    uintptr_t vram_start;
     int i;
 
     if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) {
@@ -1819,16 +1833,13 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
     }
 
     /* dirty the primary surface */
-    qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
-                  qxl->shadow_rom.surface0_area_size);
-
-    vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
+    qxl_dirty_one_surface(qxl, qxl->guest_primary.surface.mem,
+                          qxl->guest_primary.surface.height,
+                          qxl->guest_primary.surface.stride);
 
     /* dirty the off-screen surfaces */
     for (i = 0; i < qxl->ssd.num_surfaces; i++) {
         QXLSurfaceCmd *cmd;
-        intptr_t surface_offset;
-        int surface_size;
 
         if (qxl->guest_surfaces.cmds[i] == 0) {
             continue;
@@ -1838,15 +1849,9 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
                             MEMSLOT_GROUP_GUEST);
         assert(cmd);
         assert(cmd->type == QXL_SURFACE_CMD_CREATE);
-        surface_offset = (intptr_t)qxl_phys2virt(qxl,
-                                                 cmd->u.surface_create.data,
-                                                 MEMSLOT_GROUP_GUEST);
-        assert(surface_offset);
-        surface_offset -= vram_start;
-        surface_size = cmd->u.surface_create.height *
-                       abs(cmd->u.surface_create.stride);
-        trace_qxl_surfaces_dirty(qxl->id, i, (int)surface_offset, 
surface_size);
-        qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);
+        qxl_dirty_one_surface(qxl, cmd->u.surface_create.data,
+                              cmd->u.surface_create.height,
+                              cmd->u.surface_create.stride);
     }
 }
 
diff --git a/hw/display/trace-events b/hw/display/trace-events
index 30bebff..9dd82ce 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -105,7 +105,7 @@ qxl_spice_reset_image_cache(int qid) "%d"
 qxl_spice_reset_memslots(int qid) "%d"
 qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t 
right, uint32_t top, uint32_t bottom) "%d sid=%d [%d,%d,%d,%d]"
 qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t 
clear_dirty_region) "%d #d=%d clear=%d"
-qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d 
offset=%d size=%d"
+qxl_surfaces_dirty(int qid, int offset, int size) "%d offset=%d size=%d"
 qxl_send_events(int qid, uint32_t events) "%d %d"
 qxl_send_events_vm_stopped(int qid, uint32_t events) "%d %d"
 qxl_set_guest_bug(int qid) "%d"
-- 
1.8.3.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]