All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/13] vga patch queue
@ 2017-04-24 12:16 Gerd Hoffmann
  2017-04-24 12:16 ` [Qemu-devel] [PULL 01/13] console: add same surface replace pre-condition Gerd Hoffmann
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

Here comes the vga patch queue.  It brings the first batch of display
update race fixes, xres+yres properties for qxl and virtio, also some
cleanups piled up during the 2.9 freeze.

please pull,
  Gerd

The following changes since commit 32c7e0ab755745e961f1772e95cac381cc68769d:

  Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170421' into staging (2017-04-21 15:59:27 +0100)

are available in the git repository at:

  git://git.kraxel.org/qemu tags/pull-vga-20170424-1

for you to fetch changes up to 729abb6a920e80c3866f60d1638f08f2eba98a9a:

  virtio-gpu: add xres and yres properties (2017-04-24 10:12:28 +0200)

----------------------------------------------------------------
fix display update races, part one.
add xres + yres properties to qxl and virtio.
misc fixes and cleanups.

----------------------------------------------------------------
Gerd Hoffmann (10):
      bitmap: add bitmap_copy_and_clear_atomic
      memory: add support getting and using a dirty bitmap copy.
      vga: add vga_scanline_invalidated helper
      vga: make display updates thread safe.
      framebuffer: make display updates thread safe
      exynos: make display updates thread safe
      g364fb: make display updates thread safe
      vmsvga: fix vmsvga_update_display
      qxl: add xres and yres properties
      virtio-gpu: add xres and yres properties

Laurent Vivier (1):
      virtio-gpu: replace PIXMAN_* by PIXMAN_BE_*

Marc-André Lureau (2):
      console: add same surface replace pre-condition
      console: add same displaychangelistener registration pre-condition

 hw/display/qxl.h               |  2 ++
 include/exec/memory.h          | 47 ++++++++++++++++++++++++++
 include/exec/ram_addr.h        |  7 ++++
 include/hw/virtio/virtio-gpu.h |  2 ++
 include/qemu/bitmap.h          |  2 ++
 include/qemu/typedefs.h        |  1 +
 exec.c                         | 75 ++++++++++++++++++++++++++++++++++++++++++
 hw/display/exynos4210_fimd.c   | 11 ++++---
 hw/display/framebuffer.c       | 11 +++----
 hw/display/g364fb.c            | 28 +++-------------
 hw/display/qxl.c               | 34 +++++++++++++------
 hw/display/vga.c               | 50 +++++++++++++++-------------
 hw/display/virtio-gpu.c        | 41 +++++++----------------
 hw/display/vmware_vga.c        | 21 ++----------
 memory.c                       | 17 ++++++++++
 ui/console.c                   |  4 +++
 util/bitmap.c                  | 11 +++++++
 17 files changed, 251 insertions(+), 113 deletions(-)

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PULL 01/13] console: add same surface replace pre-condition
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
@ 2017-04-24 12:16 ` Gerd Hoffmann
  2017-04-24 12:16 ` [Qemu-devel] [PULL 02/13] console: add same displaychangelistener registration pre-condition Gerd Hoffmann
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Gerd Hoffmann

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Catch an invalid state early, before a potential use-after-free. This is
mainly useful for documentation purposes.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20170406120513.638-2-marcandre.lureau@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ui/console.c b/ui/console.c
index 419b098c11..0cbe5033dd 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1538,6 +1538,8 @@ void dpy_gfx_replace_surface(QemuConsole *con,
     DisplaySurface *old_surface = con->surface;
     DisplayChangeListener *dcl;
 
+    assert(old_surface != surface);
+
     con->surface = surface;
     QLIST_FOREACH(dcl, &s->listeners, next) {
         if (con != (dcl->con ? dcl->con : active_console)) {
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PULL 02/13] console: add same displaychangelistener registration pre-condition
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
  2017-04-24 12:16 ` [Qemu-devel] [PULL 01/13] console: add same surface replace pre-condition Gerd Hoffmann
@ 2017-04-24 12:16 ` Gerd Hoffmann
  2017-04-24 12:16 ` [Qemu-devel] [PULL 03/13] virtio-gpu: replace PIXMAN_* by PIXMAN_BE_* Gerd Hoffmann
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Gerd Hoffmann

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Catch an invalid state. Mainly useful for documentation purposes.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20170406120513.638-3-marcandre.lureau@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ui/console.c b/ui/console.c
index 0cbe5033dd..189eecfd29 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1410,6 +1410,8 @@ void register_displaychangelistener(DisplayChangeListener *dcl)
     static DisplaySurface *dummy;
     QemuConsole *con;
 
+    assert(!dcl->ds);
+
     if (dcl->ops->dpy_gl_ctx_create) {
         /* display has opengl support */
         assert(dcl->con);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PULL 03/13] virtio-gpu: replace PIXMAN_* by PIXMAN_BE_*
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
  2017-04-24 12:16 ` [Qemu-devel] [PULL 01/13] console: add same surface replace pre-condition Gerd Hoffmann
  2017-04-24 12:16 ` [Qemu-devel] [PULL 02/13] console: add same displaychangelistener registration pre-condition Gerd Hoffmann
@ 2017-04-24 12:16 ` Gerd Hoffmann
  2017-04-24 12:16 ` [Qemu-devel] [PULL 04/13] bitmap: add bitmap_copy_and_clear_atomic Gerd Hoffmann
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier, Gerd Hoffmann, Michael S. Tsirkin

From: Laurent Vivier <lvivier@redhat.com>

This avoids a "#ifdef HOST_WORDS_BIGENDIAN" and this is the purpose
of PIXMAN_BE_* macros.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Sahid Orentino Ferdjaoui <sahid.ferdjaoui@redhat.com>
Message-id: 20170403114044.15762-1-lvivier@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/virtio-gpu.c | 35 ++++++++---------------------------
 1 file changed, 8 insertions(+), 27 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 9b530ab5b0..7befcef8d0 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -258,41 +258,22 @@ void virtio_gpu_get_display_info(VirtIOGPU *g,
 static pixman_format_code_t get_pixman_format(uint32_t virtio_gpu_format)
 {
     switch (virtio_gpu_format) {
-#ifdef HOST_WORDS_BIGENDIAN
     case VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM:
-        return PIXMAN_b8g8r8x8;
+        return PIXMAN_BE_b8g8r8x8;
     case VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM:
-        return PIXMAN_b8g8r8a8;
+        return PIXMAN_BE_b8g8r8a8;
     case VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM:
-        return PIXMAN_x8r8g8b8;
+        return PIXMAN_BE_x8r8g8b8;
     case VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM:
-        return PIXMAN_a8r8g8b8;
+        return PIXMAN_BE_a8r8g8b8;
     case VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM:
-        return PIXMAN_r8g8b8x8;
+        return PIXMAN_BE_r8g8b8x8;
     case VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM:
-        return PIXMAN_r8g8b8a8;
+        return PIXMAN_BE_r8g8b8a8;
     case VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM:
-        return PIXMAN_x8b8g8r8;
+        return PIXMAN_BE_x8b8g8r8;
     case VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM:
-        return PIXMAN_a8b8g8r8;
-#else
-    case VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM:
-        return PIXMAN_x8r8g8b8;
-    case VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM:
-        return PIXMAN_a8r8g8b8;
-    case VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM:
-        return PIXMAN_b8g8r8x8;
-    case VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM:
-        return PIXMAN_b8g8r8a8;
-    case VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM:
-        return PIXMAN_x8b8g8r8;
-    case VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM:
-        return PIXMAN_a8b8g8r8;
-    case VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM:
-        return PIXMAN_r8g8b8x8;
-    case VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM:
-        return PIXMAN_r8g8b8a8;
-#endif
+        return PIXMAN_BE_a8b8g8r8;
     default:
         return 0;
     }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PULL 04/13] bitmap: add bitmap_copy_and_clear_atomic
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2017-04-24 12:16 ` [Qemu-devel] [PULL 03/13] virtio-gpu: replace PIXMAN_* by PIXMAN_BE_* Gerd Hoffmann
@ 2017-04-24 12:16 ` Gerd Hoffmann
  2017-04-24 12:17 ` [Qemu-devel] [PULL 05/13] memory: add support getting and using a dirty bitmap copy Gerd Hoffmann
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421091632.30900-2-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/qemu/bitmap.h |  2 ++
 util/bitmap.c         | 11 +++++++++++
 2 files changed, 13 insertions(+)

diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h
index 63ea2d0b1e..c318da12d7 100644
--- a/include/qemu/bitmap.h
+++ b/include/qemu/bitmap.h
@@ -220,6 +220,8 @@ void bitmap_set(unsigned long *map, long i, long len);
 void bitmap_set_atomic(unsigned long *map, long i, long len);
 void bitmap_clear(unsigned long *map, long start, long nr);
 bool bitmap_test_and_clear_atomic(unsigned long *map, long start, long nr);
+void bitmap_copy_and_clear_atomic(unsigned long *dst, unsigned long *src,
+                                  long nr);
 unsigned long bitmap_find_next_zero_area(unsigned long *map,
                                          unsigned long size,
                                          unsigned long start,
diff --git a/util/bitmap.c b/util/bitmap.c
index c1a84ca5e3..efced9a7d8 100644
--- a/util/bitmap.c
+++ b/util/bitmap.c
@@ -287,6 +287,17 @@ bool bitmap_test_and_clear_atomic(unsigned long *map, long start, long nr)
     return dirty != 0;
 }
 
+void bitmap_copy_and_clear_atomic(unsigned long *dst, unsigned long *src,
+                                  long nr)
+{
+    while (nr > 0) {
+        *dst = atomic_xchg(src, 0);
+        dst++;
+        src++;
+        nr -= BITS_PER_LONG;
+    }
+}
+
 #define ALIGN_MASK(x,mask)      (((x)+(mask))&~(mask))
 
 /**
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PULL 05/13] memory: add support getting and using a dirty bitmap copy.
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2017-04-24 12:16 ` [Qemu-devel] [PULL 04/13] bitmap: add bitmap_copy_and_clear_atomic Gerd Hoffmann
@ 2017-04-24 12:17 ` Gerd Hoffmann
  2017-04-24 12:17 ` [Qemu-devel] [PULL 06/13] vga: add vga_scanline_invalidated helper Gerd Hoffmann
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:17 UTC (permalink / raw)
  To: qemu-devel
  Cc: Gerd Hoffmann, Paolo Bonzini, Peter Crosthwaite, Richard Henderson

This patch adds support for getting and using a local copy of the dirty
bitmap.

memory_region_snapshot_and_clear_dirty() will create a snapshot of the
dirty bitmap for the specified range, clear the dirty bitmap and return
the copy.  The returned bitmap can be a bit larger than requested, the
range is expanded so the code can copy unsigned longs from the bitmap
and avoid atomic bit update operations.

memory_region_snapshot_get_dirty() will return the dirty status of
pages, pretty much like memory_region_get_dirty(), but using the copy
returned by memory_region_copy_and_clear_dirty().

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421091632.30900-3-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/exec/memory.h   | 47 +++++++++++++++++++++++++++++++
 include/exec/ram_addr.h |  7 +++++
 include/qemu/typedefs.h |  1 +
 exec.c                  | 75 +++++++++++++++++++++++++++++++++++++++++++++++++
 memory.c                | 17 +++++++++++
 5 files changed, 147 insertions(+)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index c4fc94d504..99e0f54d86 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -918,6 +918,53 @@ void memory_region_set_dirty(MemoryRegion *mr, hwaddr addr,
  */
 bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr,
                                         hwaddr size, unsigned client);
+
+/**
+ * memory_region_snapshot_and_clear_dirty: Get a snapshot of the dirty
+ *                                         bitmap and clear it.
+ *
+ * Creates a snapshot of the dirty bitmap, clears the dirty bitmap and
+ * returns the snapshot.  The snapshot can then be used to query dirty
+ * status, using memory_region_snapshot_get_dirty.  Unlike
+ * memory_region_test_and_clear_dirty this allows to query the same
+ * page multiple times, which is especially useful for display updates
+ * where the scanlines often are not page aligned.
+ *
+ * The dirty bitmap region which gets copyed into the snapshot (and
+ * cleared afterwards) can be larger than requested.  The boundaries
+ * are rounded up/down so complete bitmap longs (covering 64 pages on
+ * 64bit hosts) can be copied over into the bitmap snapshot.  Which
+ * isn't a problem for display updates as the extra pages are outside
+ * the visible area, and in case the visible area changes a full
+ * display redraw is due anyway.  Should other use cases for this
+ * function emerge we might have to revisit this implementation
+ * detail.
+ *
+ * Use g_free to release DirtyBitmapSnapshot.
+ *
+ * @mr: the memory region being queried.
+ * @addr: the address (relative to the start of the region) being queried.
+ * @size: the size of the range being queried.
+ * @client: the user of the logging information; typically %DIRTY_MEMORY_VGA.
+ */
+DirtyBitmapSnapshot *memory_region_snapshot_and_clear_dirty(MemoryRegion *mr,
+                                                            hwaddr addr,
+                                                            hwaddr size,
+                                                            unsigned client);
+
+/**
+ * memory_region_snapshot_get_dirty: Check whether a range of bytes is dirty
+ *                                   in the specified dirty bitmap snapshot.
+ *
+ * @mr: the memory region being queried.
+ * @snap: the dirty bitmap snapshot
+ * @addr: the address (relative to the start of the region) being queried.
+ * @size: the size of the range being queried.
+ */
+bool memory_region_snapshot_get_dirty(MemoryRegion *mr,
+                                      DirtyBitmapSnapshot *snap,
+                                      hwaddr addr, hwaddr size);
+
 /**
  * memory_region_sync_dirty_bitmap: Synchronize a region's dirty bitmap with
  *                                  any external TLBs (e.g. kvm)
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index c9ddcd0880..6436a413e7 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -343,6 +343,13 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t start,
                                               ram_addr_t length,
                                               unsigned client);
 
+DirtyBitmapSnapshot *cpu_physical_memory_snapshot_and_clear_dirty
+    (ram_addr_t start, ram_addr_t length, unsigned client);
+
+bool cpu_physical_memory_snapshot_get_dirty(DirtyBitmapSnapshot *snap,
+                                            ram_addr_t start,
+                                            ram_addr_t length);
+
 static inline void cpu_physical_memory_clear_dirty_range(ram_addr_t start,
                                                          ram_addr_t length)
 {
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index e95f28cfec..f08d327aec 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -23,6 +23,7 @@ typedef struct CPUAddressSpace CPUAddressSpace;
 typedef struct CPUState CPUState;
 typedef struct DeviceListener DeviceListener;
 typedef struct DeviceState DeviceState;
+typedef struct DirtyBitmapSnapshot DirtyBitmapSnapshot;
 typedef struct DisplayChangeListener DisplayChangeListener;
 typedef struct DisplayState DisplayState;
 typedef struct DisplaySurface DisplaySurface;
diff --git a/exec.c b/exec.c
index c2def9ecf2..eac6085760 100644
--- a/exec.c
+++ b/exec.c
@@ -223,6 +223,12 @@ struct CPUAddressSpace {
     MemoryListener tcg_as_listener;
 };
 
+struct DirtyBitmapSnapshot {
+    ram_addr_t start;
+    ram_addr_t end;
+    unsigned long dirty[];
+};
+
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
@@ -1061,6 +1067,75 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t start,
     return dirty;
 }
 
+DirtyBitmapSnapshot *cpu_physical_memory_snapshot_and_clear_dirty
+     (ram_addr_t start, ram_addr_t length, unsigned client)
+{
+    DirtyMemoryBlocks *blocks;
+    unsigned long align = 1UL << (TARGET_PAGE_BITS + BITS_PER_LEVEL);
+    ram_addr_t first = QEMU_ALIGN_DOWN(start, align);
+    ram_addr_t last  = QEMU_ALIGN_UP(start + length, align);
+    DirtyBitmapSnapshot *snap;
+    unsigned long page, end, dest;
+
+    snap = g_malloc0(sizeof(*snap) +
+                     ((last - first) >> (TARGET_PAGE_BITS + 3)));
+    snap->start = first;
+    snap->end   = last;
+
+    page = first >> TARGET_PAGE_BITS;
+    end  = last  >> TARGET_PAGE_BITS;
+    dest = 0;
+
+    rcu_read_lock();
+
+    blocks = atomic_rcu_read(&ram_list.dirty_memory[client]);
+
+    while (page < end) {
+        unsigned long idx = page / DIRTY_MEMORY_BLOCK_SIZE;
+        unsigned long offset = page % DIRTY_MEMORY_BLOCK_SIZE;
+        unsigned long num = MIN(end - page, DIRTY_MEMORY_BLOCK_SIZE - offset);
+
+        assert(QEMU_IS_ALIGNED(offset, (1 << BITS_PER_LEVEL)));
+        assert(QEMU_IS_ALIGNED(num,    (1 << BITS_PER_LEVEL)));
+        offset >>= BITS_PER_LEVEL;
+
+        bitmap_copy_and_clear_atomic(snap->dirty + dest,
+                                     blocks->blocks[idx] + offset,
+                                     num);
+        page += num;
+        dest += num >> BITS_PER_LEVEL;
+    }
+
+    rcu_read_unlock();
+
+    if (tcg_enabled()) {
+        tlb_reset_dirty_range_all(start, length);
+    }
+
+    return snap;
+}
+
+bool cpu_physical_memory_snapshot_get_dirty(DirtyBitmapSnapshot *snap,
+                                            ram_addr_t start,
+                                            ram_addr_t length)
+{
+    unsigned long page, end;
+
+    assert(start >= snap->start);
+    assert(start + length <= snap->end);
+
+    end = TARGET_PAGE_ALIGN(start + length - snap->start) >> TARGET_PAGE_BITS;
+    page = (start - snap->start) >> TARGET_PAGE_BITS;
+
+    while (page < end) {
+        if (test_bit(page, snap->dirty)) {
+            return true;
+        }
+        page++;
+    }
+    return false;
+}
+
 /* Called from RCU critical section */
 hwaddr memory_region_section_get_iotlb(CPUState *cpu,
                                        MemoryRegionSection *section,
diff --git a/memory.c b/memory.c
index b782d5bc5a..b727f5ec0e 100644
--- a/memory.c
+++ b/memory.c
@@ -1748,6 +1748,23 @@ bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr,
                 memory_region_get_ram_addr(mr) + addr, size, client);
 }
 
+DirtyBitmapSnapshot *memory_region_snapshot_and_clear_dirty(MemoryRegion *mr,
+                                                            hwaddr addr,
+                                                            hwaddr size,
+                                                            unsigned client)
+{
+    assert(mr->ram_block);
+    return cpu_physical_memory_snapshot_and_clear_dirty(
+                memory_region_get_ram_addr(mr) + addr, size, client);
+}
+
+bool memory_region_snapshot_get_dirty(MemoryRegion *mr, DirtyBitmapSnapshot *snap,
+                                      hwaddr addr, hwaddr size)
+{
+    assert(mr->ram_block);
+    return cpu_physical_memory_snapshot_get_dirty(snap,
+                memory_region_get_ram_addr(mr) + addr, size);
+}
 
 void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
 {
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PULL 06/13] vga: add vga_scanline_invalidated helper
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2017-04-24 12:17 ` [Qemu-devel] [PULL 05/13] memory: add support getting and using a dirty bitmap copy Gerd Hoffmann
@ 2017-04-24 12:17 ` Gerd Hoffmann
  2017-04-24 12:17 ` [Qemu-devel] [PULL 07/13] vga: make display updates thread safe Gerd Hoffmann
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Add vga_scanline_invalidated helper to check whenever a scanline was
invalidated.  Add a sanity check to fix OOB read access for display
heights larger than 2048.

Only cirrus uses this, for hardware cursor rendering, so having this
work properly for the first 2048 scanlines only shouldn't be a problem
as the cirrus can't handle large resolutions anyway.  Also changing the
invalidated_y_table size would break live migration.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421091632.30900-4-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/vga.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/hw/display/vga.c b/hw/display/vga.c
index 69c3e1d674..3991b88aac 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1434,6 +1434,14 @@ void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
     }
 }
 
+static bool vga_scanline_invalidated(VGACommonState *s, int y)
+{
+    if (y >= VGA_MAX_HEIGHT) {
+        return false;
+    }
+    return s->invalidated_y_table[y >> 5] & (1 << (y & 0x1f));
+}
+
 void vga_sync_dirty_bitmap(VGACommonState *s)
 {
     memory_region_sync_dirty_bitmap(&s->vram);
@@ -1638,8 +1646,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         page1 = addr + bwidth - 1;
         update |= memory_region_get_dirty(&s->vram, page0, page1 - page0,
                                           DIRTY_MEMORY_VGA);
-        /* explicit invalidation for the hardware cursor */
-        update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
+        /* explicit invalidation for the hardware cursor (cirrus only) */
+        update |= vga_scanline_invalidated(s, y);
         if (update) {
             if (y_start < 0)
                 y_start = y;
@@ -1686,7 +1694,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
                                   page_max - page_min,
                                   DIRTY_MEMORY_VGA);
     }
-    memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
+    memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table));
 }
 
 static void vga_draw_blank(VGACommonState *s, int full_update)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PULL 07/13] vga: make display updates thread safe.
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2017-04-24 12:17 ` [Qemu-devel] [PULL 06/13] vga: add vga_scanline_invalidated helper Gerd Hoffmann
@ 2017-04-24 12:17 ` Gerd Hoffmann
  2017-04-24 12:17 ` [Qemu-devel] [PULL 08/13] framebuffer: " Gerd Hoffmann
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

The vga code clears the dirty bits *after* reading the framebuffer
memory.  So if the guest framebuffer updates hits the race window
between vga reading the framebuffer and vga clearing the dirty bits
vga will miss that update

Fix it by using the new memory_region_copy_and_clear_dirty()
memory_region_copy_get_dirty() functions.  That way we clear the
dirty bitmap before reading the framebuffer.  Any guest display
updates happening in parallel will be properly tracked in the
dirty bitmap then and the next display refresh will pick them up.

Problem triggers with mttcg only.  Before mttcg was merged tcg
never ran in parallel to vga emulation.  Using kvm will hide the
problem too, due to qemu operating on a userspace copy of the
kernel's dirty bitmap.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421091632.30900-5-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/vga.c | 36 +++++++++++++++++-------------------
 1 file changed, 17 insertions(+), 19 deletions(-)

diff --git a/hw/display/vga.c b/hw/display/vga.c
index 3991b88aac..b2516c8d21 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1465,7 +1465,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     DisplaySurface *surface = qemu_console_surface(s->con);
     int y1, y, update, linesize, y_start, double_scan, mask, depth;
     int width, height, shift_control, line_offset, bwidth, bits;
-    ram_addr_t page0, page1, page_min, page_max;
+    ram_addr_t page0, page1;
+    DirtyBitmapSnapshot *snap = NULL;
     int disp_width, multi_scan, multi_run;
     uint8_t *d;
     uint32_t v, addr1, addr;
@@ -1480,9 +1481,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
 
     full_update |= update_basic_params(s);
 
-    if (!full_update)
-        vga_sync_dirty_bitmap(s);
-
     s->get_resolution(s, &width, &height);
     disp_width = width;
 
@@ -1625,11 +1623,17 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     addr1 = (s->start_addr * 4);
     bwidth = (width * bits + 7) / 8;
     y_start = -1;
-    page_min = -1;
-    page_max = 0;
     d = surface_data(surface);
     linesize = surface_stride(surface);
     y1 = 0;
+
+    if (!full_update) {
+        vga_sync_dirty_bitmap(s);
+        snap = memory_region_snapshot_and_clear_dirty(&s->vram, addr1,
+                                                      bwidth * height,
+                                                      DIRTY_MEMORY_VGA);
+    }
+
     for(y = 0; y < height; y++) {
         addr = addr1;
         if (!(s->cr[VGA_CRTC_MODE] & 1)) {
@@ -1644,17 +1648,17 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         update = full_update;
         page0 = addr;
         page1 = addr + bwidth - 1;
-        update |= memory_region_get_dirty(&s->vram, page0, page1 - page0,
-                                          DIRTY_MEMORY_VGA);
+        if (full_update) {
+            update = 1;
+        } else {
+            update = memory_region_snapshot_get_dirty(&s->vram, snap,
+                                                      page0, page1 - page0);
+        }
         /* explicit invalidation for the hardware cursor (cirrus only) */
         update |= vga_scanline_invalidated(s, y);
         if (update) {
             if (y_start < 0)
                 y_start = y;
-            if (page0 < page_min)
-                page_min = page0;
-            if (page1 > page_max)
-                page_max = page1;
             if (!(is_buffer_shared(surface))) {
                 vga_draw_line(s, d, s->vram_ptr + addr, width);
                 if (s->cursor_draw_line)
@@ -1687,13 +1691,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         dpy_gfx_update(s->con, 0, y_start,
                        disp_width, y - y_start);
     }
-    /* reset modified pages */
-    if (page_max >= page_min) {
-        memory_region_reset_dirty(&s->vram,
-                                  page_min,
-                                  page_max - page_min,
-                                  DIRTY_MEMORY_VGA);
-    }
+    g_free(snap);
     memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table));
 }
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PULL 08/13] framebuffer: make display updates thread safe
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2017-04-24 12:17 ` [Qemu-devel] [PULL 07/13] vga: make display updates thread safe Gerd Hoffmann
@ 2017-04-24 12:17 ` Gerd Hoffmann
  2017-04-24 12:17 ` [Qemu-devel] [PULL 09/13] exynos: " Gerd Hoffmann
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421091632.30900-6-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/framebuffer.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/hw/display/framebuffer.c b/hw/display/framebuffer.c
index 25aa46c8c7..d7310d25f2 100644
--- a/hw/display/framebuffer.c
+++ b/hw/display/framebuffer.c
@@ -67,7 +67,7 @@ void framebuffer_update_display(
     int *first_row, /* Input and output.  */
     int *last_row /* Output only */)
 {
-    hwaddr src_len;
+    DirtyBitmapSnapshot *snap;
     uint8_t *dest;
     uint8_t *src;
     int first, last = 0;
@@ -78,7 +78,6 @@ void framebuffer_update_display(
 
     i = *first_row;
     *first_row = -1;
-    src_len = (hwaddr)src_width * rows;
 
     mem = mem_section->mr;
     if (!mem) {
@@ -102,9 +101,10 @@ void framebuffer_update_display(
     src += i * src_width;
     dest += i * dest_row_pitch;
 
+    snap = memory_region_snapshot_and_clear_dirty(mem, addr, src_width * rows,
+                                                  DIRTY_MEMORY_VGA);
     for (; i < rows; i++) {
-        dirty = memory_region_get_dirty(mem, addr, src_width,
-                                             DIRTY_MEMORY_VGA);
+        dirty = memory_region_snapshot_get_dirty(mem, snap, addr, src_width);
         if (dirty || invalidate) {
             fn(opaque, dest, src, cols, dest_col_pitch);
             if (first == -1)
@@ -115,11 +115,10 @@ void framebuffer_update_display(
         src += src_width;
         dest += dest_row_pitch;
     }
+    g_free(snap);
     if (first < 0) {
         return;
     }
-    memory_region_reset_dirty(mem, mem_section->offset_within_region, src_len,
-                              DIRTY_MEMORY_VGA);
     *first_row = first;
     *last_row = last;
 }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PULL 09/13] exynos: make display updates thread safe
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
                   ` (7 preceding siblings ...)
  2017-04-24 12:17 ` [Qemu-devel] [PULL 08/13] framebuffer: " Gerd Hoffmann
@ 2017-04-24 12:17 ` Gerd Hoffmann
  2017-04-24 12:17 ` [Qemu-devel] [PULL 10/13] g364fb: " Gerd Hoffmann
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Igor Mitsyanko, open list:Exynos

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421091632.30900-7-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/exynos4210_fimd.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c
index e5be713406..fd0b2bec65 100644
--- a/hw/display/exynos4210_fimd.c
+++ b/hw/display/exynos4210_fimd.c
@@ -1263,6 +1263,7 @@ static void exynos4210_fimd_update(void *opaque)
     Exynos4210fimdState *s = (Exynos4210fimdState *)opaque;
     DisplaySurface *surface;
     Exynos4210fimdWindow *w;
+    DirtyBitmapSnapshot *snap;
     int i, line;
     hwaddr fb_line_addr, inc_size;
     int scrn_height;
@@ -1291,10 +1292,12 @@ static void exynos4210_fimd_update(void *opaque)
             memory_region_sync_dirty_bitmap(w->mem_section.mr);
             host_fb_addr = w->host_fb_addr;
             fb_line_addr = w->mem_section.offset_within_region;
+            snap = memory_region_snapshot_and_clear_dirty(w->mem_section.mr,
+                    fb_line_addr, inc_size * scrn_height, DIRTY_MEMORY_VGA);
 
             for (line = 0; line < scrn_height; line++) {
-                is_dirty = memory_region_get_dirty(w->mem_section.mr,
-                            fb_line_addr, scrn_width, DIRTY_MEMORY_VGA);
+                is_dirty = memory_region_snapshot_get_dirty(w->mem_section.mr,
+                            snap, fb_line_addr, scrn_width);
 
                 if (s->invalidate || is_dirty) {
                     if (first_line == -1) {
@@ -1309,9 +1312,7 @@ static void exynos4210_fimd_update(void *opaque)
                 fb_line_addr += inc_size;
                 is_dirty = false;
             }
-            memory_region_reset_dirty(w->mem_section.mr,
-                w->mem_section.offset_within_region,
-                w->fb_len, DIRTY_MEMORY_VGA);
+            g_free(snap);
             blend = true;
         }
     }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PULL 10/13] g364fb: make display updates thread safe
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
                   ` (8 preceding siblings ...)
  2017-04-24 12:17 ` [Qemu-devel] [PULL 09/13] exynos: " Gerd Hoffmann
@ 2017-04-24 12:17 ` Gerd Hoffmann
  2017-04-24 12:17 ` [Qemu-devel] [PULL 11/13] vmsvga: fix vmsvga_update_display Gerd Hoffmann
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421091632.30900-8-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/g364fb.c | 28 +++++-----------------------
 1 file changed, 5 insertions(+), 23 deletions(-)

diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c
index 8cdc205dd9..86557d14a9 100644
--- a/hw/display/g364fb.c
+++ b/hw/display/g364fb.c
@@ -64,17 +64,8 @@ typedef struct G364State {
 
 static inline int check_dirty(G364State *s, ram_addr_t page)
 {
-    return memory_region_get_dirty(&s->mem_vram, page, G364_PAGE_SIZE,
-                                   DIRTY_MEMORY_VGA);
-}
-
-static inline void reset_dirty(G364State *s,
-                               ram_addr_t page_min, ram_addr_t page_max)
-{
-    memory_region_reset_dirty(&s->mem_vram,
-                              page_min,
-                              page_max + G364_PAGE_SIZE - page_min - 1,
-                              DIRTY_MEMORY_VGA);
+    return memory_region_test_and_clear_dirty(&s->mem_vram, page, G364_PAGE_SIZE,
+                                              DIRTY_MEMORY_VGA);
 }
 
 static void g364fb_draw_graphic8(G364State *s)
@@ -83,7 +74,7 @@ static void g364fb_draw_graphic8(G364State *s)
     int i, w;
     uint8_t *vram;
     uint8_t *data_display, *dd;
-    ram_addr_t page, page_min, page_max;
+    ram_addr_t page;
     int x, y;
     int xmin, xmax;
     int ymin, ymax;
@@ -114,8 +105,6 @@ static void g364fb_draw_graphic8(G364State *s)
     }
 
     page = 0;
-    page_min = (ram_addr_t)-1;
-    page_max = 0;
 
     x = y = 0;
     xmin = s->width;
@@ -137,9 +126,6 @@ static void g364fb_draw_graphic8(G364State *s)
         if (check_dirty(s, page)) {
             if (y < ymin)
                 ymin = ymax = y;
-            if (page_min == (ram_addr_t)-1)
-                page_min = page;
-            page_max = page;
             if (x < xmin)
                 xmin = x;
             for (i = 0; i < G364_PAGE_SIZE; i++) {
@@ -196,10 +182,7 @@ static void g364fb_draw_graphic8(G364State *s)
                 ymax = y;
         } else {
             int dy;
-            if (page_min != (ram_addr_t)-1) {
-                reset_dirty(s, page_min, page_max);
-                page_min = (ram_addr_t)-1;
-                page_max = 0;
+            if (xmax || ymax) {
                 dpy_gfx_update(s->con, xmin, ymin,
                                xmax - xmin + 1, ymax - ymin + 1);
                 xmin = s->width;
@@ -219,9 +202,8 @@ static void g364fb_draw_graphic8(G364State *s)
     }
 
 done:
-    if (page_min != (ram_addr_t)-1) {
+    if (xmax || ymax) {
         dpy_gfx_update(s->con, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
-        reset_dirty(s, page_min, page_max);
     }
 }
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PULL 11/13] vmsvga: fix vmsvga_update_display
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
                   ` (9 preceding siblings ...)
  2017-04-24 12:17 ` [Qemu-devel] [PULL 10/13] g364fb: " Gerd Hoffmann
@ 2017-04-24 12:17 ` Gerd Hoffmann
  2017-04-24 12:17 ` [Qemu-devel] [PULL 12/13] qxl: add xres and yres properties Gerd Hoffmann
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Fix standard vga mode check:  Both s->config and s->enabled must be set
to enable vmware command fifo processing.

Drop dirty tracking code from the fifo rendering code path, it isn't
used anyway because vmsvga turns off dirty tracking when leaving
standard vga mode.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421091632.30900-9-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/vmware_vga.c | 21 +++------------------
 1 file changed, 3 insertions(+), 18 deletions(-)

diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index 6599cf078d..ec5f27d67e 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -1118,9 +1118,9 @@ static void vmsvga_update_display(void *opaque)
 {
     struct vmsvga_state_s *s = opaque;
     DisplaySurface *surface;
-    bool dirty = false;
 
-    if (!s->enable) {
+    if (!s->enable || !s->config) {
+        /* in standard vga mode */
         s->vga.hw_ops->gfx_update(&s->vga);
         return;
     }
@@ -1131,26 +1131,11 @@ static void vmsvga_update_display(void *opaque)
     vmsvga_fifo_run(s);
     vmsvga_update_rect_flush(s);
 
-    /*
-     * Is it more efficient to look at vram VGA-dirty bits or wait
-     * for the driver to issue SVGA_CMD_UPDATE?
-     */
-    if (memory_region_is_logging(&s->vga.vram, DIRTY_MEMORY_VGA)) {
-        vga_sync_dirty_bitmap(&s->vga);
-        dirty = memory_region_get_dirty(&s->vga.vram, 0,
-            surface_stride(surface) * surface_height(surface),
-            DIRTY_MEMORY_VGA);
-    }
-    if (s->invalidated || dirty) {
+    if (s->invalidated) {
         s->invalidated = 0;
         dpy_gfx_update(s->vga.con, 0, 0,
                    surface_width(surface), surface_height(surface));
     }
-    if (dirty) {
-        memory_region_reset_dirty(&s->vga.vram, 0,
-            surface_stride(surface) * surface_height(surface),
-            DIRTY_MEMORY_VGA);
-    }
 }
 
 static void vmsvga_reset(DeviceState *dev)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PULL 12/13] qxl: add xres and yres properties
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
                   ` (10 preceding siblings ...)
  2017-04-24 12:17 ` [Qemu-devel] [PULL 11/13] vmsvga: fix vmsvga_update_display Gerd Hoffmann
@ 2017-04-24 12:17 ` Gerd Hoffmann
  2017-04-24 12:17 ` [Qemu-devel] [PULL 13/13] virtio-gpu: " Gerd Hoffmann
  2017-04-24 15:47 ` [Qemu-devel] [PULL 00/13] vga patch queue Peter Maydell
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Add properties for the default display resolution, pass
on that information to the guest so the driver can use it.

Also move up qxl_crc32() function so we don't need a
forward declaration.

Additionally guest driver updates are needed so the
guest driver will actually pick this up, which will
probably land in linux kernel 4.12.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421092234.8368-1-kraxel@redhat.com
---
 hw/display/qxl.h |  2 ++
 hw/display/qxl.c | 34 ++++++++++++++++++++++++----------
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/hw/display/qxl.h b/hw/display/qxl.h
index 77e5a36dc5..f6556adb73 100644
--- a/hw/display/qxl.h
+++ b/hw/display/qxl.h
@@ -119,6 +119,8 @@ typedef struct PCIQXLDevice {
     uint32_t          vram_size_mb;
     uint32_t          vram32_size_mb;
     uint32_t          vgamem_size_mb;
+    uint32_t          xres;
+    uint32_t          yres;
 
     /* qxl_render_update state */
     int                render_update_cookie_num;
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 9feae78e4e..4d94cecd72 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -305,6 +305,16 @@ void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
     qxl->ssd.cursor = cursor_builtin_hidden();
 }
 
+static uint32_t qxl_crc32(const uint8_t *p, unsigned len)
+{
+    /*
+     * zlib xors the seed with 0xffffffff, and xors the result
+     * again with 0xffffffff; Both are not done with linux's crc32,
+     * which we want to be compatible with, so undo that.
+     */
+    return crc32(0xffffffff, p, len) ^ 0xffffffff;
+}
+
 static ram_addr_t qxl_rom_size(void)
 {
 #define QXL_REQUIRED_SZ (sizeof(QXLRom) + sizeof(QXLModes) + sizeof(qxl_modes))
@@ -369,6 +379,18 @@ static void init_qxl_rom(PCIQXLDevice *d)
     rom->num_pages          = cpu_to_le32(num_pages);
     rom->ram_header_offset  = cpu_to_le32(d->vga.vram_size - ram_header_size);
 
+    if (d->xres && d->yres) {
+        /* needs linux kernel 4.12+ to work */
+        rom->client_monitors_config.count = 1;
+        rom->client_monitors_config.heads[0].left = 0;
+        rom->client_monitors_config.heads[0].top = 0;
+        rom->client_monitors_config.heads[0].right = cpu_to_le32(d->xres);
+        rom->client_monitors_config.heads[0].bottom = cpu_to_le32(d->yres);
+        rom->client_monitors_config_crc = qxl_crc32(
+            (const uint8_t *)&rom->client_monitors_config,
+            sizeof(rom->client_monitors_config));
+    }
+
     d->shadow_rom = *rom;
     d->rom        = rom;
     d->modes      = modes;
@@ -1011,16 +1033,6 @@ static void interface_set_client_capabilities(QXLInstance *sin,
     qxl_send_events(qxl, QXL_INTERRUPT_CLIENT);
 }
 
-static uint32_t qxl_crc32(const uint8_t *p, unsigned len)
-{
-    /*
-     * zlib xors the seed with 0xffffffff, and xors the result
-     * again with 0xffffffff; Both are not done with linux's crc32,
-     * which we want to be compatible with, so undo that.
-     */
-    return crc32(0xffffffff, p, len) ^ 0xffffffff;
-}
-
 static bool qxl_rom_monitors_config_changed(QXLRom *rom,
         VDAgentMonitorsConfig *monitors_config,
         unsigned int max_outputs)
@@ -2397,6 +2409,8 @@ static Property qxl_properties[] = {
 #if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
         DEFINE_PROP_UINT16("max_outputs", PCIQXLDevice, max_outputs, 0),
 #endif
+        DEFINE_PROP_UINT32("xres", PCIQXLDevice, xres, 0),
+        DEFINE_PROP_UINT32("yres", PCIQXLDevice, yres, 0),
         DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PULL 13/13] virtio-gpu: add xres and yres properties
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
                   ` (11 preceding siblings ...)
  2017-04-24 12:17 ` [Qemu-devel] [PULL 12/13] qxl: add xres and yres properties Gerd Hoffmann
@ 2017-04-24 12:17 ` Gerd Hoffmann
  2017-04-24 15:47 ` [Qemu-devel] [PULL 00/13] vga patch queue Peter Maydell
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2017-04-24 12:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Michael S. Tsirkin

So the default resolution is configurable.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20170421092214.8176-1-kraxel@redhat.com
---
 include/hw/virtio/virtio-gpu.h | 2 ++
 hw/display/virtio-gpu.c        | 6 ++++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index f3a98a3261..f3ffdceca4 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -72,6 +72,8 @@ struct virtio_gpu_conf {
     uint64_t max_hostmem;
     uint32_t max_outputs;
     uint32_t flags;
+    uint32_t xres;
+    uint32_t yres;
 };
 
 struct virtio_gpu_ctrl_command {
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 7befcef8d0..e1056f34df 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1151,8 +1151,8 @@ static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
     virtio_init(VIRTIO_DEVICE(g), "virtio-gpu", VIRTIO_ID_GPU,
                 g->config_size);
 
-    g->req_state[0].width = 1024;
-    g->req_state[0].height = 768;
+    g->req_state[0].width = g->conf.xres;
+    g->req_state[0].height = g->conf.yres;
 
     if (virtio_gpu_virgl_enabled(g->conf)) {
         /* use larger control queue in 3d mode */
@@ -1272,6 +1272,8 @@ static Property virtio_gpu_properties[] = {
     DEFINE_PROP_BIT("stats", VirtIOGPU, conf.flags,
                     VIRTIO_GPU_FLAG_STATS_ENABLED, false),
 #endif
+    DEFINE_PROP_UINT32("xres", VirtIOGPU, conf.xres, 1024),
+    DEFINE_PROP_UINT32("yres", VirtIOGPU, conf.yres, 768),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PULL 00/13] vga patch queue
  2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
                   ` (12 preceding siblings ...)
  2017-04-24 12:17 ` [Qemu-devel] [PULL 13/13] virtio-gpu: " Gerd Hoffmann
@ 2017-04-24 15:47 ` Peter Maydell
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2017-04-24 15:47 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: QEMU Developers

On 24 April 2017 at 13:16, Gerd Hoffmann <kraxel@redhat.com> wrote:
>   Hi,
>
> Here comes the vga patch queue.  It brings the first batch of display
> update race fixes, xres+yres properties for qxl and virtio, also some
> cleanups piled up during the 2.9 freeze.
>
> please pull,
>   Gerd
>
> The following changes since commit 32c7e0ab755745e961f1772e95cac381cc68769d:
>
>   Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170421' into staging (2017-04-21 15:59:27 +0100)
>
> are available in the git repository at:
>
>   git://git.kraxel.org/qemu tags/pull-vga-20170424-1
>
> for you to fetch changes up to 729abb6a920e80c3866f60d1638f08f2eba98a9a:
>
>   virtio-gpu: add xres and yres properties (2017-04-24 10:12:28 +0200)
>
> ----------------------------------------------------------------
> fix display update races, part one.
> add xres + yres properties to qxl and virtio.
> misc fixes and cleanups.
>
> ----------------------------------------------------------------

Applied, thanks.

-- PMM

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2017-04-24 15:47 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-24 12:16 [Qemu-devel] [PULL 00/13] vga patch queue Gerd Hoffmann
2017-04-24 12:16 ` [Qemu-devel] [PULL 01/13] console: add same surface replace pre-condition Gerd Hoffmann
2017-04-24 12:16 ` [Qemu-devel] [PULL 02/13] console: add same displaychangelistener registration pre-condition Gerd Hoffmann
2017-04-24 12:16 ` [Qemu-devel] [PULL 03/13] virtio-gpu: replace PIXMAN_* by PIXMAN_BE_* Gerd Hoffmann
2017-04-24 12:16 ` [Qemu-devel] [PULL 04/13] bitmap: add bitmap_copy_and_clear_atomic Gerd Hoffmann
2017-04-24 12:17 ` [Qemu-devel] [PULL 05/13] memory: add support getting and using a dirty bitmap copy Gerd Hoffmann
2017-04-24 12:17 ` [Qemu-devel] [PULL 06/13] vga: add vga_scanline_invalidated helper Gerd Hoffmann
2017-04-24 12:17 ` [Qemu-devel] [PULL 07/13] vga: make display updates thread safe Gerd Hoffmann
2017-04-24 12:17 ` [Qemu-devel] [PULL 08/13] framebuffer: " Gerd Hoffmann
2017-04-24 12:17 ` [Qemu-devel] [PULL 09/13] exynos: " Gerd Hoffmann
2017-04-24 12:17 ` [Qemu-devel] [PULL 10/13] g364fb: " Gerd Hoffmann
2017-04-24 12:17 ` [Qemu-devel] [PULL 11/13] vmsvga: fix vmsvga_update_display Gerd Hoffmann
2017-04-24 12:17 ` [Qemu-devel] [PULL 12/13] qxl: add xres and yres properties Gerd Hoffmann
2017-04-24 12:17 ` [Qemu-devel] [PULL 13/13] virtio-gpu: " Gerd Hoffmann
2017-04-24 15:47 ` [Qemu-devel] [PULL 00/13] vga patch queue Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.