9ae3a8
From 03b4fe1dacb0e4a2bdebb86d11e1cff13b2972c1 Mon Sep 17 00:00:00 2001
9ae3a8
From: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
Date: Tue, 7 Feb 2017 10:07:50 +0100
9ae3a8
Subject: [PATCH 07/11] cirrus: allow zero source pitch in pattern fill rops
9ae3a8
9ae3a8
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
Message-id: <1486462072-32174-6-git-send-email-kraxel@redhat.com>
9ae3a8
Patchwork-id: 73569
9ae3a8
O-Subject: [RHEL-7.4 qemu-kvm PATCH 5/7] cirrus: allow zero source pitch in pattern fill rops
9ae3a8
Bugzilla: 1418233
9ae3a8
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
9ae3a8
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
9ae3a8
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
9ae3a8
9ae3a8
The rops used by cirrus_bitblt_common_patterncopy only use
9ae3a8
the destination pitch, so the source pitch shoul allowed to
9ae3a8
be zero and the blit with used for the range check around the
9ae3a8
source address.
9ae3a8
9ae3a8
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
9ae3a8
Message-id: 1485272138-23249-1-git-send-email-w.bumiller@proxmox.com
9ae3a8
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
(cherry picked from commit 5858dd1801883309bdd208d72ddb81c4e9fee30c)
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 hw/display/cirrus_vga.c | 27 +++++++++++++++++++--------
9ae3a8
 1 file changed, 19 insertions(+), 8 deletions(-)
9ae3a8
9ae3a8
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
9ae3a8
index e09076a..b040ab1 100644
9ae3a8
--- a/hw/display/cirrus_vga.c
9ae3a8
+++ b/hw/display/cirrus_vga.c
9ae3a8
@@ -267,9 +267,6 @@ static void cirrus_update_memory_access(CirrusVGAState *s);
9ae3a8
 static bool blit_region_is_unsafe(struct CirrusVGAState *s,
9ae3a8
                                   int32_t pitch, int32_t addr)
9ae3a8
 {
9ae3a8
-    if (!pitch) {
9ae3a8
-        return true;
9ae3a8
-    }
9ae3a8
     if (pitch < 0) {
9ae3a8
         int64_t min = addr
9ae3a8
             + ((int64_t)s->cirrus_blt_height-1) * pitch;
9ae3a8
@@ -289,8 +286,11 @@ static bool blit_region_is_unsafe(struct CirrusVGAState *s,
9ae3a8
     return false;
9ae3a8
 }
9ae3a8
 
9ae3a8
-static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only)
9ae3a8
+static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only,
9ae3a8
+                           bool zero_src_pitch_ok)
9ae3a8
 {
9ae3a8
+    int32_t check_pitch;
9ae3a8
+
9ae3a8
     /* should be the case, see cirrus_bitblt_start */
9ae3a8
     assert(s->cirrus_blt_width > 0);
9ae3a8
     assert(s->cirrus_blt_height > 0);
9ae3a8
@@ -299,6 +299,10 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only)
9ae3a8
         return true;
9ae3a8
     }
9ae3a8
 
9ae3a8
+    if (!s->cirrus_blt_dstpitch) {
9ae3a8
+        return true;
9ae3a8
+    }
9ae3a8
+
9ae3a8
     if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch,
9ae3a8
                               s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) {
9ae3a8
         return true;
9ae3a8
@@ -306,7 +310,13 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only)
9ae3a8
     if (dst_only) {
9ae3a8
         return false;
9ae3a8
     }
9ae3a8
-    if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch,
9ae3a8
+
9ae3a8
+    check_pitch = s->cirrus_blt_srcpitch;
9ae3a8
+    if (!zero_src_pitch_ok && !check_pitch) {
9ae3a8
+        check_pitch = s->cirrus_blt_width;
9ae3a8
+    }
9ae3a8
+
9ae3a8
+    if (blit_region_is_unsafe(s, check_pitch,
9ae3a8
                               s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) {
9ae3a8
         return true;
9ae3a8
     }
9ae3a8
@@ -676,8 +686,9 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
9ae3a8
 
9ae3a8
     dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
9ae3a8
 
9ae3a8
-    if (blit_is_unsafe(s, false))
9ae3a8
+    if (blit_is_unsafe(s, false, true)) {
9ae3a8
         return 0;
9ae3a8
+    }
9ae3a8
 
9ae3a8
     (*s->cirrus_rop) (s, dst, src,
9ae3a8
                       s->cirrus_blt_dstpitch, 0,
9ae3a8
@@ -694,7 +705,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
9ae3a8
 {
9ae3a8
     cirrus_fill_t rop_func;
9ae3a8
 
9ae3a8
-    if (blit_is_unsafe(s, true)) {
9ae3a8
+    if (blit_is_unsafe(s, true, true)) {
9ae3a8
         return 0;
9ae3a8
     }
9ae3a8
     rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
9ae3a8
@@ -798,7 +809,7 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
9ae3a8
 
9ae3a8
 static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
9ae3a8
 {
9ae3a8
-    if (blit_is_unsafe(s, false))
9ae3a8
+    if (blit_is_unsafe(s, false, false))
9ae3a8
         return 0;
9ae3a8
 
9ae3a8
     return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
9ae3a8
-- 
9ae3a8
1.8.3.1
9ae3a8