9ae3a8
From 13bf417cd4063f5db2f0a79265745481d4c69d0d Mon Sep 17 00:00:00 2001
9ae3a8
From: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
Date: Fri, 22 Jul 2016 09:34:40 +0200
9ae3a8
Subject: [PATCH 3/4] qxl: fix surface migration
9ae3a8
9ae3a8
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
Message-id: <1469180081-28522-4-git-send-email-kraxel@redhat.com>
9ae3a8
Patchwork-id: 71315
9ae3a8
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 3/4] qxl: fix surface migration
9ae3a8
Bugzilla: 1355730
9ae3a8
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
9ae3a8
RH-Acked-by: John Snow <jsnow@redhat.com>
9ae3a8
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
9ae3a8
9ae3a8
Create a helper function qxl_dirty_one_surface() to mark a single qxl
9ae3a8
surface as dirty.  Use the new qxl_get_check_slot_offset function and
9ae3a8
lookup the memory region from the slot instead of assuming the surface
9ae3a8
is stored in vram.
9ae3a8
9ae3a8
Use the new helper function in qxl_dirty_surfaces, for both primary and
9ae3a8
off-screen surfaces.  For off-screen surfaces this is no functional
9ae3a8
change.  For primary surfaces this will dirty only the memory actually
9ae3a8
used instead of the whole surface0 region.  It will also work correctly
9ae3a8
in case the guest places the primary surface in vram instead of the
9ae3a8
surface0 region (linux kms driver does that).
9ae3a8
9ae3a8
https://bugzilla.redhat.com/show_bug.cgi?id=1235732
9ae3a8
9ae3a8
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
Message-id: 1466597244-5938-3-git-send-email-kraxel@redhat.com
9ae3a8
(cherry picked from commit 1331eab216c9dc4e50a48a34d14926b31a7fd611)
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
9ae3a8
Conflicts:
9ae3a8
	hw/display/trace-events
9ae3a8
---
9ae3a8
 hw/display/qxl.c | 37 +++++++++++++++++++++----------------
9ae3a8
 trace-events     |  2 +-
9ae3a8
 2 files changed, 22 insertions(+), 17 deletions(-)
9ae3a8
9ae3a8
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
9ae3a8
index de5770e..d65c830 100644
9ae3a8
--- a/hw/display/qxl.c
9ae3a8
+++ b/hw/display/qxl.c
9ae3a8
@@ -1822,9 +1822,23 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
9ae3a8
     }
9ae3a8
 }
9ae3a8
 
9ae3a8
+static void qxl_dirty_one_surface(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
9ae3a8
+                                  uint32_t height, int32_t stride)
9ae3a8
+{
9ae3a8
+    uint64_t offset;
9ae3a8
+    uint32_t slot, size;
9ae3a8
+    bool rc;
9ae3a8
+
9ae3a8
+    rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset);
9ae3a8
+    assert(rc == true);
9ae3a8
+    size = height * abs(stride);
9ae3a8
+    trace_qxl_surfaces_dirty(qxl->id, (int)offset, size);
9ae3a8
+    qxl_set_dirty(qxl->guest_slots[slot].mr,
9ae3a8
+                  qxl->guest_slots[slot].offset + offset, size);
9ae3a8
+}
9ae3a8
+
9ae3a8
 static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
9ae3a8
 {
9ae3a8
-    uintptr_t vram_start;
9ae3a8
     int i;
9ae3a8
 
9ae3a8
     if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) {
9ae3a8
@@ -1832,16 +1846,13 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
9ae3a8
     }
9ae3a8
 
9ae3a8
     /* dirty the primary surface */
9ae3a8
-    qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
9ae3a8
-                  qxl->shadow_rom.surface0_area_size);
9ae3a8
-
9ae3a8
-    vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
9ae3a8
+    qxl_dirty_one_surface(qxl, qxl->guest_primary.surface.mem,
9ae3a8
+                          qxl->guest_primary.surface.height,
9ae3a8
+                          qxl->guest_primary.surface.stride);
9ae3a8
 
9ae3a8
     /* dirty the off-screen surfaces */
9ae3a8
     for (i = 0; i < qxl->ssd.num_surfaces; i++) {
9ae3a8
         QXLSurfaceCmd *cmd;
9ae3a8
-        intptr_t surface_offset;
9ae3a8
-        int surface_size;
9ae3a8
 
9ae3a8
         if (qxl->guest_surfaces.cmds[i] == 0) {
9ae3a8
             continue;
9ae3a8
@@ -1851,15 +1862,9 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
9ae3a8
                             MEMSLOT_GROUP_GUEST);
9ae3a8
         assert(cmd);
9ae3a8
         assert(cmd->type == QXL_SURFACE_CMD_CREATE);
9ae3a8
-        surface_offset = (intptr_t)qxl_phys2virt(qxl,
9ae3a8
-                                                 cmd->u.surface_create.data,
9ae3a8
-                                                 MEMSLOT_GROUP_GUEST);
9ae3a8
-        assert(surface_offset);
9ae3a8
-        surface_offset -= vram_start;
9ae3a8
-        surface_size = cmd->u.surface_create.height *
9ae3a8
-                       abs(cmd->u.surface_create.stride);
9ae3a8
-        trace_qxl_surfaces_dirty(qxl->id, i, (int)surface_offset, surface_size);
9ae3a8
-        qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);
9ae3a8
+        qxl_dirty_one_surface(qxl, cmd->u.surface_create.data,
9ae3a8
+                              cmd->u.surface_create.height,
9ae3a8
+                              cmd->u.surface_create.stride);
9ae3a8
     }
9ae3a8
 }
9ae3a8
 
9ae3a8
diff --git a/trace-events b/trace-events
9ae3a8
index b43132c..4da84b2 100644
9ae3a8
--- a/trace-events
9ae3a8
+++ b/trace-events
9ae3a8
@@ -1078,7 +1078,7 @@ qxl_spice_reset_image_cache(int qid) "%d"
9ae3a8
 qxl_spice_reset_memslots(int qid) "%d"
9ae3a8
 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]"
9ae3a8
 qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d"
9ae3a8
-qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d"
9ae3a8
+qxl_surfaces_dirty(int qid, int offset, int size) "%d offset=%d size=%d"
9ae3a8
 qxl_send_events(int qid, uint32_t events) "%d %d"
9ae3a8
 qxl_send_events_vm_stopped(int qid, uint32_t events) "%d %d"
9ae3a8
 qxl_set_guest_bug(int qid) "%d"
9ae3a8
-- 
9ae3a8
1.8.3.1
9ae3a8