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