ae23c9
From 9fbf6794bed827af4d1248b25d175f014a47201d Mon Sep 17 00:00:00 2001
ae23c9
From: Gerd Hoffmann <kraxel@redhat.com>
ae23c9
Date: Tue, 29 May 2018 10:57:04 +0200
ae23c9
Subject: [PATCH 004/268] vga: catch depth 0
ae23c9
ae23c9
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
ae23c9
Message-id: <20180529105704.21419-2-kraxel@redhat.com>
ae23c9
Patchwork-id: 80500
ae23c9
O-Subject: [RHEL-7.6 qemu-kvm-rhev PATCH 1/1] vga: catch depth 0
ae23c9
Bugzilla: 1575541
ae23c9
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
ae23c9
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
ae23c9
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
ae23c9
ae23c9
depth == 0 is used to indicate 256 color modes.  Our region calculation
ae23c9
goes wrong in that case.  So detect that and just take the safe code
ae23c9
path we already have for the wraparound case.
ae23c9
ae23c9
While being at it also catch depth == 15 (where our region size
ae23c9
calculation goes wrong too).  And make the comment more verbose,
ae23c9
explaining what is going on here.
ae23c9
ae23c9
Without this windows guest install might trigger an assert due to trying
ae23c9
to check dirty bitmap outside the snapshot region.
ae23c9
ae23c9
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1575541
ae23c9
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
ae23c9
Message-id: 20180514103117.21059-1-kraxel@redhat.com
ae23c9
(cherry picked from commit a89fe6c329799e47aaa1663650f076b28808e186)
ae23c9
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
ae23c9
---
ae23c9
 hw/display/vga.c | 23 ++++++++++++++++++-----
ae23c9
 1 file changed, 18 insertions(+), 5 deletions(-)
ae23c9
ae23c9
diff --git a/hw/display/vga.c b/hw/display/vga.c
ae23c9
index 7218133..a7794f6 100644
ae23c9
--- a/hw/display/vga.c
ae23c9
+++ b/hw/display/vga.c
ae23c9
@@ -1480,13 +1480,28 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
ae23c9
 
ae23c9
     s->get_resolution(s, &width, &height);
ae23c9
     disp_width = width;
ae23c9
+    depth = s->get_bpp(s);
ae23c9
 
ae23c9
     region_start = (s->start_addr * 4);
ae23c9
     region_end = region_start + (ram_addr_t)s->line_offset * height;
ae23c9
-    region_end += width * s->get_bpp(s) / 8; /* scanline length */
ae23c9
+    region_end += width * depth / 8; /* scanline length */
ae23c9
     region_end -= s->line_offset;
ae23c9
-    if (region_end > s->vbe_size) {
ae23c9
-        /* wraps around (can happen with cirrus vbe modes) */
ae23c9
+    if (region_end > s->vbe_size || depth == 0 || depth == 15) {
ae23c9
+        /*
ae23c9
+         * We land here on:
ae23c9
+         *  - wraps around (can happen with cirrus vbe modes)
ae23c9
+         *  - depth == 0 (256 color palette video mode)
ae23c9
+         *  - depth == 15
ae23c9
+         *
ae23c9
+         * Take the safe and slow route:
ae23c9
+         *   - create a dirty bitmap snapshot for all vga memory.
ae23c9
+         *   - force shadowing (so all vga memory access goes
ae23c9
+         *     through vga_read_*() helpers).
ae23c9
+         *
ae23c9
+         * Given this affects only vga features which are pretty much
ae23c9
+         * unused by modern guests there should be no performance
ae23c9
+         * impact.
ae23c9
+         */
ae23c9
         region_start = 0;
ae23c9
         region_end = s->vbe_size;
ae23c9
         force_shadow = true;
ae23c9
@@ -1520,8 +1535,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
ae23c9
         }
ae23c9
     }
ae23c9
 
ae23c9
-    depth = s->get_bpp(s);
ae23c9
-
ae23c9
     /*
ae23c9
      * Check whether we can share the surface with the backend
ae23c9
      * or whether we need a shadow surface. We share native
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9