diff --git a/SOURCES/kvm-cirrus-add-option-to-disable-blitter.patch b/SOURCES/kvm-cirrus-add-option-to-disable-blitter.patch new file mode 100644 index 0000000..47d8984 --- /dev/null +++ b/SOURCES/kvm-cirrus-add-option-to-disable-blitter.patch @@ -0,0 +1,84 @@ +From 319f3876fafc35412bbf0ef6797c6764c95af6f3 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 21 Mar 2017 09:58:03 +0100 +Subject: [PATCH 3/7] cirrus: add option to disable blitter + +RH-Author: Gerd Hoffmann +Message-id: <1490090287-1503-4-git-send-email-kraxel@redhat.com> +Patchwork-id: 74424 +O-Subject: [RHEL-7.4 qemu-kvm PATCH 3/7] cirrus: add option to disable blitter +Bugzilla: 1430059 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +Ok, we have this beast in the cirrus code which is not used at all by +modern guests, except when you try to find security holes in qemu. So, +add an option to disable blitter altogether. Guests released within +the last ten years should not show any rendering issues if you turn off +blitter support. + +There are no known bugs in the cirrus blitter code. But in the past we +hoped a few times already that we've finally nailed the last issue. So +having some easy way to mitigate in case yet another blitter issue shows +up certainly makes me sleep a bit better at night. + +For completeness: The by far better way to mitigate is to switch away +from cirrus and use stdvga instead. Or something more modern like +virtio-vga in case your guest has support for it. + +Signed-off-by: Gerd Hoffmann +Message-id: 1489494540-15745-1-git-send-email-kraxel@redhat.com +(cherry picked from commit 827bd5172641f2a360ff9a3bad57bcf82e7f03f0) +Signed-off-by: Miroslav Rezanina + +Conflicts: + hw/display/cirrus_vga.c +--- + hw/display/cirrus_vga.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index 83cef70..86b4c8b 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -203,6 +203,7 @@ typedef struct CirrusVGAState { + uint8_t cirrus_hidden_palette[48]; + uint32_t hw_cursor_x; + uint32_t hw_cursor_y; ++ bool enable_blitter; + int cirrus_blt_pixelwidth; + int cirrus_blt_width; + int cirrus_blt_height; +@@ -954,6 +955,10 @@ static void cirrus_bitblt_start(CirrusVGAState * s) + { + uint8_t blt_rop; + ++ if (!s->enable_blitter) { ++ goto bitblt_ignore; ++ } ++ + s->vga.gr[0x31] |= CIRRUS_BLT_BUSY; + + s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1; +@@ -2995,6 +3000,8 @@ static int vga_initfn(ISADevice *dev) + static Property isa_cirrus_vga_properties[] = { + DEFINE_PROP_UINT32("vgamem_mb", struct ISACirrusVGAState, + cirrus_vga.vga.vram_size_mb, 16), ++ DEFINE_PROP_BOOL("blitter", struct ISACirrusVGAState, ++ cirrus_vga.enable_blitter, true), + DEFINE_PROP_END_OF_LIST(), + }; + +@@ -3060,6 +3067,8 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev) + static Property pci_vga_cirrus_properties[] = { + DEFINE_PROP_UINT32("vgamem_mb", struct PCICirrusVGAState, + cirrus_vga.vga.vram_size_mb, 16), ++ DEFINE_PROP_BOOL("blitter", struct PCICirrusVGAState, ++ cirrus_vga.enable_blitter, true), + DEFINE_PROP_END_OF_LIST(), + }; + +-- +1.8.3.1 + diff --git a/SOURCES/kvm-cirrus-fix-cirrus_invalidate_region.patch b/SOURCES/kvm-cirrus-fix-cirrus_invalidate_region.patch new file mode 100644 index 0000000..b180965 --- /dev/null +++ b/SOURCES/kvm-cirrus-fix-cirrus_invalidate_region.patch @@ -0,0 +1,51 @@ +From 6c17f6355cac0bc40bae876acf4d31e32978991f Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 21 Mar 2017 09:58:04 +0100 +Subject: [PATCH 4/7] cirrus: fix cirrus_invalidate_region + +RH-Author: Gerd Hoffmann +Message-id: <1490090287-1503-5-git-send-email-kraxel@redhat.com> +Patchwork-id: 74423 +O-Subject: [RHEL-7.4 qemu-kvm PATCH 4/7] cirrus: fix cirrus_invalidate_region +Bugzilla: 1430059 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +off_cur_end is exclusive, so off_cur_end == cirrus_addr_mask is valid. +Fix calculation to make sure to allow that, otherwise the assert added +by commit f153b563f8cf121aebf5a2fff5f0110faf58ccb3 can trigger for valid +blits. + +Test case: boot windows nt 4.0 + +Signed-off-by: Gerd Hoffmann +Message-id: 1489579606-26020-1-git-send-email-kraxel@redhat.com +(cherry picked from commit e048dac616748273c2153490e9fdf1da242f0cad) +Signed-off-by: Miroslav Rezanina +--- + hw/display/cirrus_vga.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index 86b4c8b..aab6e02 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -661,11 +661,11 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, + } + + for (y = 0; y < lines; y++) { +- off_cur = off_begin; +- off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask; ++ off_cur = off_begin; ++ off_cur_end = ((off_cur + bytesperline - 1) & s->cirrus_addr_mask) + 1; + assert(off_cur_end >= off_cur); + memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur); +- off_begin += off_pitch; ++ off_begin += off_pitch; + } + } + +-- +1.8.3.1 + diff --git a/SOURCES/kvm-cirrus-fix-off-by-one-in-cirrus_bitblt_rop_bkwd_tran.patch b/SOURCES/kvm-cirrus-fix-off-by-one-in-cirrus_bitblt_rop_bkwd_tran.patch new file mode 100644 index 0000000..6188818 --- /dev/null +++ b/SOURCES/kvm-cirrus-fix-off-by-one-in-cirrus_bitblt_rop_bkwd_tran.patch @@ -0,0 +1,49 @@ +From 8c2a803f9ba8b4293c207917a2acfcfac0548d24 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 21 Mar 2017 09:58:07 +0100 +Subject: [PATCH 7/7] cirrus: fix off-by-one in + cirrus_bitblt_rop_bkwd_transp_*_16 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Gerd Hoffmann +Message-id: <1490090287-1503-8-git-send-email-kraxel@redhat.com> +Patchwork-id: 74422 +O-Subject: [RHEL-7.4 qemu-kvm PATCH 7/7] cirrus: fix off-by-one in cirrus_bitblt_rop_bkwd_transp_*_16 +Bugzilla: 1430059 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +The switch from pointers to addresses (commit +026aeffcb4752054830ba203020ed6eb05bcaba8 and +ffaf857778286ca54e3804432a2369a279e73aa7) added +a off-by-one bug to 16bit backward blits. Fix. + +Reported-by: 李强 +Signed-off-by: Gerd Hoffmann +Reviewed-by: Li Qiang +Message-id: 1489735296-19047-1-git-send-email-kraxel@redhat.com +(cherry picked from commit f019722cbbb45aea153294fc8921fcc96a4d3fa2) +Signed-off-by: Miroslav Rezanina +--- + hw/display/cirrus_vga_rop.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/display/cirrus_vga_rop.h b/hw/display/cirrus_vga_rop.h +index 16dffb8..c1fc070 100644 +--- a/hw/display/cirrus_vga_rop.h ++++ b/hw/display/cirrus_vga_rop.h +@@ -220,7 +220,7 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, + srcpitch += bltwidth; + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x+=2) { +- ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp); ++ ROP_OP_TR_16(s, dstaddr - 1, cirrus_src16(s, srcaddr - 1), transp); + dstaddr -= 2; + srcaddr -= 2; + } +-- +1.8.3.1 + diff --git a/SOURCES/kvm-cirrus-stop-passing-around-dst-pointers-in-the-blitt.patch b/SOURCES/kvm-cirrus-stop-passing-around-dst-pointers-in-the-blitt.patch new file mode 100644 index 0000000..2425a76 --- /dev/null +++ b/SOURCES/kvm-cirrus-stop-passing-around-dst-pointers-in-the-blitt.patch @@ -0,0 +1,630 @@ +From c4928f394f862c78024f4dccb6ea1398dc743c49 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 21 Mar 2017 09:58:05 +0100 +Subject: [PATCH 5/7] cirrus: stop passing around dst pointers in the blitter + +RH-Author: Gerd Hoffmann +Message-id: <1490090287-1503-6-git-send-email-kraxel@redhat.com> +Patchwork-id: 74421 +O-Subject: [RHEL-7.4 qemu-kvm PATCH 5/7] cirrus: stop passing around dst pointers in the blitter +Bugzilla: 1430059 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +Instead pass around the address (aka offset into vga memory). Calculate +the pointer in the rop_* functions, after applying the mask to the +address, to make sure the address stays within the valid range. + +Signed-off-by: Gerd Hoffmann +Message-id: 1489574872-8679-1-git-send-email-kraxel@redhat.com +(cherry picked from commit 026aeffcb4752054830ba203020ed6eb05bcaba8) +Signed-off-by: Miroslav Rezanina +--- + hw/display/cirrus_vga.c | 20 +++--- + hw/display/cirrus_vga_rop.h | 161 +++++++++++++++++++++++++------------------ + hw/display/cirrus_vga_rop2.h | 97 +++++++++++++------------- + 3 files changed, 153 insertions(+), 125 deletions(-) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index aab6e02..003cc4c 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -174,11 +174,12 @@ + + struct CirrusVGAState; + typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s, +- uint8_t * dst, const uint8_t * src, ++ uint32_t dstaddr, const uint8_t *src, + int dstpitch, int srcpitch, + int bltwidth, int bltheight); + typedef void (*cirrus_fill_t)(struct CirrusVGAState *s, +- uint8_t *dst, int dst_pitch, int width, int height); ++ uint32_t dstaddr, int dst_pitch, ++ int width, int height); + + typedef struct CirrusVGAState { + VGACommonState vga; +@@ -315,14 +316,14 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only) + } + + static void cirrus_bitblt_rop_nop(CirrusVGAState *s, +- uint8_t *dst,const uint8_t *src, ++ uint32_t dstaddr, const uint8_t *src, + int dstpitch,int srcpitch, + int bltwidth,int bltheight) + { + } + + static void cirrus_bitblt_fill_nop(CirrusVGAState *s, +- uint8_t *dst, ++ uint32_t dstaddr, + int dstpitch, int bltwidth,int bltheight) + { + } +@@ -672,11 +673,8 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, + static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc) + { + uint32_t patternsize; +- uint8_t *dst; + uint8_t *src; + +- dst = s->vga.vram_ptr + s->cirrus_blt_dstaddr; +- + if (videosrc) { + switch (s->vga.get_bpp(&s->vga)) { + case 8: +@@ -705,7 +703,7 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc) + return 0; + } + +- (*s->cirrus_rop) (s, dst, src, ++ (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr, src, + s->cirrus_blt_dstpitch, 0, + s->cirrus_blt_width, s->cirrus_blt_height); + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, +@@ -724,7 +722,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) + return 0; + } + rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; +- rop_func(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr, ++ rop_func(s, s->cirrus_blt_dstaddr, + s->cirrus_blt_dstpitch, + s->cirrus_blt_width, s->cirrus_blt_height); + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, +@@ -791,7 +789,7 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) + } + } + +- (*s->cirrus_rop) (s, s->vga.vram_ptr + s->cirrus_blt_dstaddr, ++ (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr, + s->vga.vram_ptr + s->cirrus_blt_srcaddr, + s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, + s->cirrus_blt_width, s->cirrus_blt_height); +@@ -842,7 +840,7 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s) + } else { + /* at least one scan line */ + do { +- (*s->cirrus_rop)(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr, ++ (*s->cirrus_rop)(s, s->cirrus_blt_dstaddr, + s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1); + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0, + s->cirrus_blt_width, 1); +diff --git a/hw/display/cirrus_vga_rop.h b/hw/display/cirrus_vga_rop.h +index a4f96c6..3b16d70 100644 +--- a/hw/display/cirrus_vga_rop.h ++++ b/hw/display/cirrus_vga_rop.h +@@ -22,31 +22,65 @@ + * THE SOFTWARE. + */ + +-static inline void glue(rop_8_,ROP_NAME)(uint8_t *dst, uint8_t src) ++static inline void glue(rop_8_, ROP_NAME)(CirrusVGAState *s, ++ uint32_t dstaddr, uint8_t src) + { ++ uint8_t *dst = &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask]; + *dst = ROP_FN(*dst, src); + } + +-static inline void glue(rop_16_,ROP_NAME)(uint16_t *dst, uint16_t src) ++static inline void glue(rop_tr_8_, ROP_NAME)(CirrusVGAState *s, ++ uint32_t dstaddr, uint8_t src, ++ uint8_t transp) + { ++ uint8_t *dst = &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask]; ++ uint8_t pixel = ROP_FN(*dst, src); ++ if (pixel != transp) { ++ *dst = pixel; ++ } ++} ++ ++static inline void glue(rop_16_, ROP_NAME)(CirrusVGAState *s, ++ uint32_t dstaddr, uint16_t src) ++{ ++ uint16_t *dst = (uint16_t *) ++ (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]); + *dst = ROP_FN(*dst, src); + } + +-static inline void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src) ++static inline void glue(rop_tr_16_, ROP_NAME)(CirrusVGAState *s, ++ uint32_t dstaddr, uint16_t src, ++ uint16_t transp) ++{ ++ uint16_t *dst = (uint16_t *) ++ (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]); ++ uint16_t pixel = ROP_FN(*dst, src); ++ if (pixel != transp) { ++ *dst = pixel; ++ } ++} ++ ++static inline void glue(rop_32_, ROP_NAME)(CirrusVGAState *s, ++ uint32_t dstaddr, uint32_t src) + { ++ uint32_t *dst = (uint32_t *) ++ (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~3]); + *dst = ROP_FN(*dst, src); + } + +-#define ROP_OP(d, s) glue(rop_8_,ROP_NAME)(d, s) +-#define ROP_OP_16(d, s) glue(rop_16_,ROP_NAME)(d, s) +-#define ROP_OP_32(d, s) glue(rop_32_,ROP_NAME)(d, s) ++#define ROP_OP(st, d, s) glue(rop_8_, ROP_NAME)(st, d, s) ++#define ROP_OP_TR(st, d, s, t) glue(rop_tr_8_, ROP_NAME)(st, d, s, t) ++#define ROP_OP_16(st, d, s) glue(rop_16_, ROP_NAME)(st, d, s) ++#define ROP_OP_TR_16(st, d, s, t) glue(rop_tr_16_, ROP_NAME)(st, d, s, t) ++#define ROP_OP_32(st, d, s) glue(rop_32_, ROP_NAME)(st, d, s) + #undef ROP_FN + + static void + glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s, +- uint8_t *dst,const uint8_t *src, +- int dstpitch,int srcpitch, +- int bltwidth,int bltheight) ++ uint32_t dstaddr, ++ const uint8_t *src, ++ int dstpitch, int srcpitch, ++ int bltwidth, int bltheight) + { + int x,y; + dstpitch -= bltwidth; +@@ -59,43 +93,47 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s, + + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x++) { +- ROP_OP(dst, *src); +- dst++; ++ ROP_OP(s, dstaddr, *src); ++ dstaddr++; + src++; + } +- dst += dstpitch; ++ dstaddr += dstpitch; + src += srcpitch; + } + } + + static void + glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s, +- uint8_t *dst,const uint8_t *src, +- int dstpitch,int srcpitch, +- int bltwidth,int bltheight) ++ uint32_t dstaddr, ++ const uint8_t *src, ++ int dstpitch, int srcpitch, ++ int bltwidth, int bltheight) + { + int x,y; + dstpitch += bltwidth; + srcpitch += bltwidth; + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x++) { +- ROP_OP(dst, *src); +- dst--; ++ ROP_OP(s, dstaddr, *src); ++ dstaddr--; + src--; + } +- dst += dstpitch; ++ dstaddr += dstpitch; + src += srcpitch; + } + } + + static void + glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, +- uint8_t *dst,const uint8_t *src, +- int dstpitch,int srcpitch, +- int bltwidth,int bltheight) ++ uint32_t dstaddr, ++ const uint8_t *src, ++ int dstpitch, ++ int srcpitch, ++ int bltwidth, ++ int bltheight) + { + int x,y; +- uint8_t p; ++ uint8_t transp = s->vga.gr[0x34]; + dstpitch -= bltwidth; + srcpitch -= bltwidth; + +@@ -105,48 +143,50 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, + + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x++) { +- p = *dst; +- ROP_OP(&p, *src); +- if (p != s->vga.gr[0x34]) *dst = p; +- dst++; ++ ROP_OP_TR(s, dstaddr, *src, transp); ++ dstaddr++; + src++; + } +- dst += dstpitch; ++ dstaddr += dstpitch; + src += srcpitch; + } + } + + static void + glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, +- uint8_t *dst,const uint8_t *src, +- int dstpitch,int srcpitch, +- int bltwidth,int bltheight) ++ uint32_t dstaddr, ++ const uint8_t *src, ++ int dstpitch, ++ int srcpitch, ++ int bltwidth, ++ int bltheight) + { + int x,y; +- uint8_t p; ++ uint8_t transp = s->vga.gr[0x34]; + dstpitch += bltwidth; + srcpitch += bltwidth; + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x++) { +- p = *dst; +- ROP_OP(&p, *src); +- if (p != s->vga.gr[0x34]) *dst = p; +- dst--; ++ ROP_OP_TR(s, dstaddr, *src, transp); ++ dstaddr--; + src--; + } +- dst += dstpitch; ++ dstaddr += dstpitch; + src += srcpitch; + } + } + + static void + glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, +- uint8_t *dst,const uint8_t *src, +- int dstpitch,int srcpitch, +- int bltwidth,int bltheight) ++ uint32_t dstaddr, ++ const uint8_t *src, ++ int dstpitch, ++ int srcpitch, ++ int bltwidth, ++ int bltheight) + { + int x,y; +- uint8_t p1, p2; ++ uint16_t transp = s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8; + dstpitch -= bltwidth; + srcpitch -= bltwidth; + +@@ -156,46 +196,35 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, + + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x+=2) { +- p1 = *dst; +- p2 = *(dst+1); +- ROP_OP(&p1, *src); +- ROP_OP(&p2, *(src + 1)); +- if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) { +- *dst = p1; +- *(dst+1) = p2; +- } +- dst+=2; +- src+=2; ++ ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp); ++ dstaddr += 2; ++ src += 2; + } +- dst += dstpitch; ++ dstaddr += dstpitch; + src += srcpitch; + } + } + + static void + glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, +- uint8_t *dst,const uint8_t *src, +- int dstpitch,int srcpitch, +- int bltwidth,int bltheight) ++ uint32_t dstaddr, ++ const uint8_t *src, ++ int dstpitch, ++ int srcpitch, ++ int bltwidth, ++ int bltheight) + { + int x,y; +- uint8_t p1, p2; ++ uint16_t transp = s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8; + dstpitch += bltwidth; + srcpitch += bltwidth; + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x+=2) { +- p1 = *(dst-1); +- p2 = *dst; +- ROP_OP(&p1, *(src - 1)); +- ROP_OP(&p2, *src); +- if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) { +- *(dst-1) = p1; +- *dst = p2; +- } +- dst-=2; +- src-=2; ++ ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp); ++ dstaddr -= 2; ++ src -= 2; + } +- dst += dstpitch; ++ dstaddr += dstpitch; + src += srcpitch; + } + } +diff --git a/hw/display/cirrus_vga_rop2.h b/hw/display/cirrus_vga_rop2.h +index d28bcc6..bc92f0e 100644 +--- a/hw/display/cirrus_vga_rop2.h ++++ b/hw/display/cirrus_vga_rop2.h +@@ -23,27 +23,29 @@ + */ + + #if DEPTH == 8 +-#define PUTPIXEL() ROP_OP(&d[0], col) ++#define PUTPIXEL(s, a, c) ROP_OP(s, a, c) + #elif DEPTH == 16 +-#define PUTPIXEL() ROP_OP_16((uint16_t *)&d[0], col) ++#define PUTPIXEL(s, a, c) ROP_OP_16(s, a, c) + #elif DEPTH == 24 +-#define PUTPIXEL() ROP_OP(&d[0], col); \ +- ROP_OP(&d[1], (col >> 8)); \ +- ROP_OP(&d[2], (col >> 16)) ++#define PUTPIXEL(s, a, c) do { \ ++ ROP_OP(s, a, c); \ ++ ROP_OP(s, a + 1, (col >> 8)); \ ++ ROP_OP(s, a + 2, (col >> 16)); \ ++ } while (0) + #elif DEPTH == 32 +-#define PUTPIXEL() ROP_OP_32(((uint32_t *)&d[0]), col) ++#define PUTPIXEL(s, a, c) ROP_OP_32(s, a, c) + #else + #error unsupported DEPTH + #endif + + static void + glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) +- (CirrusVGAState * s, uint8_t * dst, +- const uint8_t * src, ++ (CirrusVGAState *s, uint32_t dstaddr, ++ const uint8_t *src, + int dstpitch, int srcpitch, + int bltwidth, int bltheight) + { +- uint8_t *d; ++ uint32_t addr; + int x, y, pattern_y, pattern_pitch, pattern_x; + unsigned int col; + const uint8_t *src1; +@@ -63,7 +65,7 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) + pattern_y = s->cirrus_blt_srcaddr & 7; + for(y = 0; y < bltheight; y++) { + pattern_x = skipleft; +- d = dst + skipleft; ++ addr = dstaddr + skipleft; + src1 = src + pattern_y * pattern_pitch; + for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) { + #if DEPTH == 8 +@@ -82,23 +84,23 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) + col = ((uint32_t *)(src1 + pattern_x))[0]; + pattern_x = (pattern_x + 4) & 31; + #endif +- PUTPIXEL(); +- d += (DEPTH / 8); ++ PUTPIXEL(s, addr, col); ++ addr += (DEPTH / 8); + } + pattern_y = (pattern_y + 1) & 7; +- dst += dstpitch; ++ dstaddr += dstpitch; + } + } + + /* NOTE: srcpitch is ignored */ + static void + glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) +- (CirrusVGAState * s, uint8_t * dst, +- const uint8_t * src, ++ (CirrusVGAState *s, uint32_t dstaddr, ++ const uint8_t *src, + int dstpitch, int srcpitch, + int bltwidth, int bltheight) + { +- uint8_t *d; ++ uint32_t addr; + int x, y; + unsigned bits, bits_xor; + unsigned int col; +@@ -123,7 +125,7 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) + for(y = 0; y < bltheight; y++) { + bitmask = 0x80 >> srcskipleft; + bits = *src++ ^ bits_xor; +- d = dst + dstskipleft; ++ addr = dstaddr + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { + if ((bitmask & 0xff) == 0) { + bitmask = 0x80; +@@ -131,24 +133,24 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) + } + index = (bits & bitmask); + if (index) { +- PUTPIXEL(); ++ PUTPIXEL(s, addr, col); + } +- d += (DEPTH / 8); ++ addr += (DEPTH / 8); + bitmask >>= 1; + } +- dst += dstpitch; ++ dstaddr += dstpitch; + } + } + + static void + glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) +- (CirrusVGAState * s, uint8_t * dst, +- const uint8_t * src, ++ (CirrusVGAState *s, uint32_t dstaddr, ++ const uint8_t *src, + int dstpitch, int srcpitch, + int bltwidth, int bltheight) + { + uint32_t colors[2]; +- uint8_t *d; ++ uint32_t addr; + int x, y; + unsigned bits; + unsigned int col; +@@ -161,29 +163,29 @@ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) + for(y = 0; y < bltheight; y++) { + bitmask = 0x80 >> srcskipleft; + bits = *src++; +- d = dst + dstskipleft; ++ addr = dstaddr + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { + if ((bitmask & 0xff) == 0) { + bitmask = 0x80; + bits = *src++; + } + col = colors[!!(bits & bitmask)]; +- PUTPIXEL(); +- d += (DEPTH / 8); ++ PUTPIXEL(s, addr, col); ++ addr += (DEPTH / 8); + bitmask >>= 1; + } +- dst += dstpitch; ++ dstaddr += dstpitch; + } + } + + static void + glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH) +- (CirrusVGAState * s, uint8_t * dst, +- const uint8_t * src, ++ (CirrusVGAState *s, uint32_t dstaddr, ++ const uint8_t *src, + int dstpitch, int srcpitch, + int bltwidth, int bltheight) + { +- uint8_t *d; ++ uint32_t addr; + int x, y, bitpos, pattern_y; + unsigned int bits, bits_xor; + unsigned int col; +@@ -207,28 +209,28 @@ glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH) + for(y = 0; y < bltheight; y++) { + bits = src[pattern_y] ^ bits_xor; + bitpos = 7 - srcskipleft; +- d = dst + dstskipleft; ++ addr = dstaddr + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { + if ((bits >> bitpos) & 1) { +- PUTPIXEL(); ++ PUTPIXEL(s, addr, col); + } +- d += (DEPTH / 8); ++ addr += (DEPTH / 8); + bitpos = (bitpos - 1) & 7; + } + pattern_y = (pattern_y + 1) & 7; +- dst += dstpitch; ++ dstaddr += dstpitch; + } + } + + static void + glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH) +- (CirrusVGAState * s, uint8_t * dst, +- const uint8_t * src, ++ (CirrusVGAState *s, uint32_t dstaddr, ++ const uint8_t *src, + int dstpitch, int srcpitch, + int bltwidth, int bltheight) + { + uint32_t colors[2]; +- uint8_t *d; ++ uint32_t addr; + int x, y, bitpos, pattern_y; + unsigned int bits; + unsigned int col; +@@ -242,38 +244,37 @@ glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH) + for(y = 0; y < bltheight; y++) { + bits = src[pattern_y]; + bitpos = 7 - srcskipleft; +- d = dst + dstskipleft; ++ addr = dstaddr + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { + col = colors[(bits >> bitpos) & 1]; +- PUTPIXEL(); +- d += (DEPTH / 8); ++ PUTPIXEL(s, addr, col); ++ addr += (DEPTH / 8); + bitpos = (bitpos - 1) & 7; + } + pattern_y = (pattern_y + 1) & 7; +- dst += dstpitch; ++ dstaddr += dstpitch; + } + } + + static void + glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH) + (CirrusVGAState *s, +- uint8_t *dst, int dst_pitch, ++ uint32_t dstaddr, int dst_pitch, + int width, int height) + { +- uint8_t *d, *d1; ++ uint32_t addr; + uint32_t col; + int x, y; + + col = s->cirrus_blt_fgcol; + +- d1 = dst; + for(y = 0; y < height; y++) { +- d = d1; ++ addr = dstaddr; + for(x = 0; x < width; x += (DEPTH / 8)) { +- PUTPIXEL(); +- d += (DEPTH / 8); ++ PUTPIXEL(s, addr, col); ++ addr += (DEPTH / 8); + } +- d1 += dst_pitch; ++ dstaddr += dst_pitch; + } + } + +-- +1.8.3.1 + diff --git a/SOURCES/kvm-cirrus-stop-passing-around-src-pointers-in-the-blitt.patch b/SOURCES/kvm-cirrus-stop-passing-around-src-pointers-in-the-blitt.patch new file mode 100644 index 0000000..29837cc --- /dev/null +++ b/SOURCES/kvm-cirrus-stop-passing-around-src-pointers-in-the-blitt.patch @@ -0,0 +1,455 @@ +From d29af2a00b6126d2c3af535d128beeb80216c197 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 21 Mar 2017 09:58:06 +0100 +Subject: [PATCH 6/7] cirrus: stop passing around src pointers in the blitter + +RH-Author: Gerd Hoffmann +Message-id: <1490090287-1503-7-git-send-email-kraxel@redhat.com> +Patchwork-id: 74417 +O-Subject: [RHEL-7.4 qemu-kvm PATCH 6/7] cirrus: stop passing around src pointers in the blitter +Bugzilla: 1430059 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +Does basically the same as "cirrus: stop passing around dst pointers in +the blitter", just for the src pointer instead of the dst pointer. + +For the src we have to care about cputovideo blits though and fetch the +data from s->cirrus_bltbuf instead of vga memory. The cirrus_src*() +helper functions handle that. + +Signed-off-by: Gerd Hoffmann +Message-id: 1489584487-3489-1-git-send-email-kraxel@redhat.com +(cherry picked from commit ffaf857778286ca54e3804432a2369a279e73aa7) +Signed-off-by: Miroslav Rezanina +--- + hw/display/cirrus_vga.c | 61 +++++++++++++++++++++++++++++++++++--------- + hw/display/cirrus_vga_rop.h | 48 +++++++++++++++++----------------- + hw/display/cirrus_vga_rop2.h | 38 ++++++++++++++------------- + 3 files changed, 93 insertions(+), 54 deletions(-) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index 003cc4c..c1324ab 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -174,7 +174,7 @@ + + struct CirrusVGAState; + typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s, +- uint32_t dstaddr, const uint8_t *src, ++ uint32_t dstaddr, uint32_t srcaddr, + int dstpitch, int srcpitch, + int bltwidth, int bltheight); + typedef void (*cirrus_fill_t)(struct CirrusVGAState *s, +@@ -316,7 +316,7 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only) + } + + static void cirrus_bitblt_rop_nop(CirrusVGAState *s, +- uint32_t dstaddr, const uint8_t *src, ++ uint32_t dstaddr, uint32_t srcaddr, + int dstpitch,int srcpitch, + int bltwidth,int bltheight) + { +@@ -328,6 +328,45 @@ static void cirrus_bitblt_fill_nop(CirrusVGAState *s, + { + } + ++static inline uint8_t cirrus_src(CirrusVGAState *s, uint32_t srcaddr) ++{ ++ if (s->cirrus_srccounter) { ++ /* cputovideo */ ++ return s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1)]; ++ } else { ++ /* videotovideo */ ++ return s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask]; ++ } ++} ++ ++static inline uint16_t cirrus_src16(CirrusVGAState *s, uint32_t srcaddr) ++{ ++ uint16_t *src; ++ ++ if (s->cirrus_srccounter) { ++ /* cputovideo */ ++ src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~1]; ++ } else { ++ /* videotovideo */ ++ src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~1]; ++ } ++ return *src; ++} ++ ++static inline uint32_t cirrus_src32(CirrusVGAState *s, uint32_t srcaddr) ++{ ++ uint32_t *src; ++ ++ if (s->cirrus_srccounter) { ++ /* cputovideo */ ++ src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~3]; ++ } else { ++ /* videotovideo */ ++ src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~3]; ++ } ++ return *src; ++} ++ + #define ROP_NAME 0 + #define ROP_FN(d, s) 0 + #include "cirrus_vga_rop.h" +@@ -670,10 +709,10 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, + } + } + +-static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc) ++static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s) + { + uint32_t patternsize; +- uint8_t *src; ++ bool videosrc = !s->cirrus_srccounter; + + if (videosrc) { + switch (s->vga.get_bpp(&s->vga)) { +@@ -694,16 +733,14 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc) + if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) { + return 0; + } +- src = s->vga.vram_ptr + s->cirrus_blt_srcaddr; +- } else { +- src = s->cirrus_bltbuf; + } + + if (blit_is_unsafe(s, true)) { + return 0; + } + +- (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr, src, ++ (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr, ++ videosrc ? s->cirrus_blt_srcaddr : 0, + s->cirrus_blt_dstpitch, 0, + s->cirrus_blt_width, s->cirrus_blt_height); + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, +@@ -740,7 +777,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) + + static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) + { +- return cirrus_bitblt_common_patterncopy(s, true); ++ return cirrus_bitblt_common_patterncopy(s); + } + + static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) +@@ -790,7 +827,7 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) + } + + (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr, +- s->vga.vram_ptr + s->cirrus_blt_srcaddr, ++ s->cirrus_blt_srcaddr, + s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, + s->cirrus_blt_width, s->cirrus_blt_height); + +@@ -833,7 +870,7 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s) + + if (s->cirrus_srccounter > 0) { + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { +- cirrus_bitblt_common_patterncopy(s, false); ++ cirrus_bitblt_common_patterncopy(s); + the_end: + s->cirrus_srccounter = 0; + cirrus_bitblt_reset(s); +@@ -841,7 +878,7 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s) + /* at least one scan line */ + do { + (*s->cirrus_rop)(s, s->cirrus_blt_dstaddr, +- s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1); ++ 0, 0, 0, s->cirrus_blt_width, 1); + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0, + s->cirrus_blt_width, 1); + s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch; +diff --git a/hw/display/cirrus_vga_rop.h b/hw/display/cirrus_vga_rop.h +index 3b16d70..16dffb8 100644 +--- a/hw/display/cirrus_vga_rop.h ++++ b/hw/display/cirrus_vga_rop.h +@@ -78,7 +78,7 @@ static inline void glue(rop_32_, ROP_NAME)(CirrusVGAState *s, + static void + glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s, + uint32_t dstaddr, +- const uint8_t *src, ++ uint32_t srcaddr, + int dstpitch, int srcpitch, + int bltwidth, int bltheight) + { +@@ -93,19 +93,19 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s, + + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x++) { +- ROP_OP(s, dstaddr, *src); ++ ROP_OP(s, dstaddr, cirrus_src(s, srcaddr)); + dstaddr++; +- src++; ++ srcaddr++; + } + dstaddr += dstpitch; +- src += srcpitch; ++ srcaddr += srcpitch; + } + } + + static void + glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s, + uint32_t dstaddr, +- const uint8_t *src, ++ uint32_t srcaddr, + int dstpitch, int srcpitch, + int bltwidth, int bltheight) + { +@@ -114,19 +114,19 @@ glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s, + srcpitch += bltwidth; + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x++) { +- ROP_OP(s, dstaddr, *src); ++ ROP_OP(s, dstaddr, cirrus_src(s, srcaddr)); + dstaddr--; +- src--; ++ srcaddr--; + } + dstaddr += dstpitch; +- src += srcpitch; ++ srcaddr += srcpitch; + } + } + + static void + glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, + uint32_t dstaddr, +- const uint8_t *src, ++ uint32_t srcaddr, + int dstpitch, + int srcpitch, + int bltwidth, +@@ -143,19 +143,19 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, + + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x++) { +- ROP_OP_TR(s, dstaddr, *src, transp); ++ ROP_OP_TR(s, dstaddr, cirrus_src(s, srcaddr), transp); + dstaddr++; +- src++; ++ srcaddr++; + } + dstaddr += dstpitch; +- src += srcpitch; ++ srcaddr += srcpitch; + } + } + + static void + glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, + uint32_t dstaddr, +- const uint8_t *src, ++ uint32_t srcaddr, + int dstpitch, + int srcpitch, + int bltwidth, +@@ -167,19 +167,19 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, + srcpitch += bltwidth; + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x++) { +- ROP_OP_TR(s, dstaddr, *src, transp); ++ ROP_OP_TR(s, dstaddr, cirrus_src(s, srcaddr), transp); + dstaddr--; +- src--; ++ srcaddr--; + } + dstaddr += dstpitch; +- src += srcpitch; ++ srcaddr += srcpitch; + } + } + + static void + glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, + uint32_t dstaddr, +- const uint8_t *src, ++ uint32_t srcaddr, + int dstpitch, + int srcpitch, + int bltwidth, +@@ -196,19 +196,19 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, + + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x+=2) { +- ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp); ++ ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp); + dstaddr += 2; +- src += 2; ++ srcaddr += 2; + } + dstaddr += dstpitch; +- src += srcpitch; ++ srcaddr += srcpitch; + } + } + + static void + glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, + uint32_t dstaddr, +- const uint8_t *src, ++ uint32_t srcaddr, + int dstpitch, + int srcpitch, + int bltwidth, +@@ -220,12 +220,12 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, + srcpitch += bltwidth; + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x+=2) { +- ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp); ++ ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp); + dstaddr -= 2; +- src -= 2; ++ srcaddr -= 2; + } + dstaddr += dstpitch; +- src += srcpitch; ++ srcaddr += srcpitch; + } + } + +diff --git a/hw/display/cirrus_vga_rop2.h b/hw/display/cirrus_vga_rop2.h +index bc92f0e..b86bcd6 100644 +--- a/hw/display/cirrus_vga_rop2.h ++++ b/hw/display/cirrus_vga_rop2.h +@@ -41,14 +41,14 @@ + static void + glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) + (CirrusVGAState *s, uint32_t dstaddr, +- const uint8_t *src, ++ uint32_t srcaddr, + int dstpitch, int srcpitch, + int bltwidth, int bltheight) + { + uint32_t addr; + int x, y, pattern_y, pattern_pitch, pattern_x; + unsigned int col; +- const uint8_t *src1; ++ uint32_t src1addr; + #if DEPTH == 24 + int skipleft = s->vga.gr[0x2f] & 0x1f; + #else +@@ -66,22 +66,24 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) + for(y = 0; y < bltheight; y++) { + pattern_x = skipleft; + addr = dstaddr + skipleft; +- src1 = src + pattern_y * pattern_pitch; ++ src1addr = srcaddr + pattern_y * pattern_pitch; + for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) { + #if DEPTH == 8 +- col = src1[pattern_x]; ++ col = cirrus_src(s, src1addr + pattern_x); + pattern_x = (pattern_x + 1) & 7; + #elif DEPTH == 16 +- col = ((uint16_t *)(src1 + pattern_x))[0]; ++ col = cirrus_src16(s, src1addr + pattern_x); + pattern_x = (pattern_x + 2) & 15; + #elif DEPTH == 24 + { +- const uint8_t *src2 = src1 + pattern_x * 3; +- col = src2[0] | (src2[1] << 8) | (src2[2] << 16); ++ uint32_t src2addr = src1addr + pattern_x * 3; ++ col = cirrus_src(s, src2addr) | ++ (cirrus_src(s, src2addr + 1) << 8) | ++ (cirrus_src(s, src2addr + 2) << 16); + pattern_x = (pattern_x + 1) & 7; + } + #else +- col = ((uint32_t *)(src1 + pattern_x))[0]; ++ col = cirrus_src32(s, src1addr + pattern_x); + pattern_x = (pattern_x + 4) & 31; + #endif + PUTPIXEL(s, addr, col); +@@ -96,7 +98,7 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) + static void + glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) + (CirrusVGAState *s, uint32_t dstaddr, +- const uint8_t *src, ++ uint32_t srcaddr, + int dstpitch, int srcpitch, + int bltwidth, int bltheight) + { +@@ -124,12 +126,12 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) + + for(y = 0; y < bltheight; y++) { + bitmask = 0x80 >> srcskipleft; +- bits = *src++ ^ bits_xor; ++ bits = cirrus_src(s, srcaddr++) ^ bits_xor; + addr = dstaddr + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { + if ((bitmask & 0xff) == 0) { + bitmask = 0x80; +- bits = *src++ ^ bits_xor; ++ bits = cirrus_src(s, srcaddr++) ^ bits_xor; + } + index = (bits & bitmask); + if (index) { +@@ -145,7 +147,7 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) + static void + glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) + (CirrusVGAState *s, uint32_t dstaddr, +- const uint8_t *src, ++ uint32_t srcaddr, + int dstpitch, int srcpitch, + int bltwidth, int bltheight) + { +@@ -162,12 +164,12 @@ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) + colors[1] = s->cirrus_blt_fgcol; + for(y = 0; y < bltheight; y++) { + bitmask = 0x80 >> srcskipleft; +- bits = *src++; ++ bits = cirrus_src(s, srcaddr++); + addr = dstaddr + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { + if ((bitmask & 0xff) == 0) { + bitmask = 0x80; +- bits = *src++; ++ bits = cirrus_src(s, srcaddr++); + } + col = colors[!!(bits & bitmask)]; + PUTPIXEL(s, addr, col); +@@ -181,7 +183,7 @@ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) + static void + glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH) + (CirrusVGAState *s, uint32_t dstaddr, +- const uint8_t *src, ++ uint32_t srcaddr, + int dstpitch, int srcpitch, + int bltwidth, int bltheight) + { +@@ -207,7 +209,7 @@ glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH) + pattern_y = s->cirrus_blt_srcaddr & 7; + + for(y = 0; y < bltheight; y++) { +- bits = src[pattern_y] ^ bits_xor; ++ bits = cirrus_src(s, srcaddr + pattern_y) ^ bits_xor; + bitpos = 7 - srcskipleft; + addr = dstaddr + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { +@@ -225,7 +227,7 @@ glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH) + static void + glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH) + (CirrusVGAState *s, uint32_t dstaddr, +- const uint8_t *src, ++ uint32_t srcaddr, + int dstpitch, int srcpitch, + int bltwidth, int bltheight) + { +@@ -242,7 +244,7 @@ glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH) + pattern_y = s->cirrus_blt_srcaddr & 7; + + for(y = 0; y < bltheight; y++) { +- bits = src[pattern_y]; ++ bits = cirrus_src(s, srcaddr + pattern_y); + bitpos = 7 - srcskipleft; + addr = dstaddr + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { +-- +1.8.3.1 + diff --git a/SOURCES/kvm-cirrus-vnc-zap-bitblit-support-from-console-code.patch b/SOURCES/kvm-cirrus-vnc-zap-bitblit-support-from-console-code.patch new file mode 100644 index 0000000..854e932 --- /dev/null +++ b/SOURCES/kvm-cirrus-vnc-zap-bitblit-support-from-console-code.patch @@ -0,0 +1,297 @@ +From de457fc23e747a0c622e0fd23e49893c1f1da460 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 21 Mar 2017 09:58:02 +0100 +Subject: [PATCH 2/7] cirrus/vnc: zap bitblit support from console code. + +RH-Author: Gerd Hoffmann +Message-id: <1490090287-1503-3-git-send-email-kraxel@redhat.com> +Patchwork-id: 74418 +O-Subject: [RHEL-7.4 qemu-kvm PATCH 2/7] cirrus/vnc: zap bitblit support from console code. +Bugzilla: 1430059 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +There is a special code path (dpy_gfx_copy) to allow graphic emulation +notify user interface code about bitblit operations carryed out by +guests. It is supported by cirrus and vnc server. The intended purpose +is to optimize display scrolls and just send over the scroll op instead +of a full display update. + +This is rarely used these days though because modern guests simply don't +use the cirrus blitter any more. Any linux guest using the cirrus drm +driver doesn't. Any windows guest newer than winxp doesn't ship with a +cirrus driver any more and thus uses the cirrus as simple framebuffer. + +So this code tends to bitrot and bugs can go unnoticed for a long time. +See for example commit "3e10c3e vnc: fix qemu crash because of SIGSEGV" +which fixes a bug lingering in the code for almost a year, added by +commit "c7628bf vnc: only alloc server surface with clients connected". + +Also the vnc server will throttle the frame rate in case it figures the +network can't keep up (send buffers are full). This doesn't work with +dpy_gfx_copy, for any copy operation sent to the vnc client we have to +send all outstanding updates beforehand, otherwise the vnc client might +run the client side blit on outdated data and thereby corrupt the +display. So this dpy_gfx_copy "optimization" might even make things +worse on slow network links. + +Lets kill it once for all. + +Oh, and one more reason: Turns out (after writing the patch) we have a +security bug in that code path ... + +Fixes: CVE-2016-9603 +Signed-off-by: Gerd Hoffmann +Message-id: 1489494419-14340-1-git-send-email-kraxel@redhat.com +(cherry picked from commit 50628d3479e4f9aa97e323506856e394fe7ad7a6) +Signed-off-by: Miroslav Rezanina + +Conflicts: + include/ui/console.h + ui/vnc.c +--- + hw/display/cirrus_vga.c | 12 ++----- + include/ui/console.h | 7 ---- + ui/console.c | 28 --------------- + ui/vnc.c | 96 ------------------------------------------------- + 4 files changed, 3 insertions(+), 140 deletions(-) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index 1b972db..83cef70 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -790,21 +790,15 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) + } + } + +- /* we have to flush all pending changes so that the copy +- is generated at the appropriate moment in time */ +- if (notify) +- graphic_hw_update(s->vga.con); +- + (*s->cirrus_rop) (s, s->vga.vram_ptr + s->cirrus_blt_dstaddr, + s->vga.vram_ptr + s->cirrus_blt_srcaddr, + s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, + s->cirrus_blt_width, s->cirrus_blt_height); + + if (notify) { +- qemu_console_copy(s->vga.con, +- sx, sy, dx, dy, +- s->cirrus_blt_width / depth, +- s->cirrus_blt_height); ++ dpy_gfx_update(s->vga.con, dx, dy, ++ s->cirrus_blt_width / depth, ++ s->cirrus_blt_height); + } + + /* we don't have to notify the display that this portion has +diff --git a/include/ui/console.h b/include/ui/console.h +index 4307b5f..7f5fa66 100644 +--- a/include/ui/console.h ++++ b/include/ui/console.h +@@ -159,9 +159,6 @@ typedef struct DisplayChangeListenerOps { + int x, int y, int w, int h); + void (*dpy_gfx_switch)(DisplayChangeListener *dcl, + struct DisplaySurface *new_surface); +- void (*dpy_gfx_copy)(DisplayChangeListener *dcl, +- int src_x, int src_y, +- int dst_x, int dst_y, int w, int h); + + void (*dpy_text_cursor)(DisplayChangeListener *dcl, + int x, int y); +@@ -216,8 +213,6 @@ void unregister_displaychangelistener(DisplayChangeListener *dcl); + void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h); + void dpy_gfx_replace_surface(QemuConsole *con, + DisplaySurface *surface); +-void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y, +- int dst_x, int dst_y, int w, int h); + void dpy_text_cursor(QemuConsole *con, int x, int y); + void dpy_text_update(QemuConsole *con, int x, int y, int w, int h); + void dpy_text_resize(QemuConsole *con, int w, int h); +@@ -295,8 +290,6 @@ void text_consoles_set_display(DisplayState *ds); + void console_select(unsigned int index); + void console_color_init(DisplayState *ds); + void qemu_console_resize(QemuConsole *con, int width, int height); +-void qemu_console_copy(QemuConsole *con, int src_x, int src_y, +- int dst_x, int dst_y, int w, int h); + DisplaySurface *qemu_console_surface(QemuConsole *con); + DisplayState *qemu_console_displaystate(QemuConsole *console); + +diff --git a/ui/console.c b/ui/console.c +index d422083..fb08ec0 100644 +--- a/ui/console.c ++++ b/ui/console.c +@@ -1461,27 +1461,6 @@ void dpy_refresh(DisplayState *s) + } + } + +-void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y, +- int dst_x, int dst_y, int w, int h) +-{ +- DisplayState *s = con->ds; +- DisplayChangeListener *dcl; +- +- if (!qemu_console_is_visible(con)) { +- return; +- } +- QLIST_FOREACH(dcl, &s->listeners, next) { +- if (con != (dcl->con ? dcl->con : active_console)) { +- continue; +- } +- if (dcl->ops->dpy_gfx_copy) { +- dcl->ops->dpy_gfx_copy(dcl, src_x, src_y, dst_x, dst_y, w, h); +- } else { /* TODO */ +- dcl->ops->dpy_gfx_update(dcl, dst_x, dst_y, w, h); +- } +- } +-} +- + void dpy_text_cursor(QemuConsole *con, int x, int y) + { + DisplayState *s = con->ds; +@@ -1843,13 +1822,6 @@ void qemu_console_resize(QemuConsole *s, int width, int height) + dpy_gfx_replace_surface(s, surface); + } + +-void qemu_console_copy(QemuConsole *con, int src_x, int src_y, +- int dst_x, int dst_y, int w, int h) +-{ +- assert(con->console_type == GRAPHIC_CONSOLE); +- dpy_gfx_copy(con, src_x, src_y, dst_x, dst_y, w, h); +-} +- + DisplaySurface *qemu_console_surface(QemuConsole *console) + { + return console->surface; +diff --git a/ui/vnc.c b/ui/vnc.c +index a0e2d33..c7a7853 100644 +--- a/ui/vnc.c ++++ b/ui/vnc.c +@@ -417,7 +417,6 @@ out_error: + */ + + static int vnc_update_client(VncState *vs, int has_dirty); +-static int vnc_update_client_sync(VncState *vs, int has_dirty); + static void vnc_disconnect_start(VncState *vs); + + static void vnc_colordepth(VncState *vs); +@@ -721,93 +720,6 @@ int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) + return n; + } + +-static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h) +-{ +- /* send bitblit op to the vnc client */ +- vnc_lock_output(vs); +- vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); +- vnc_write_u8(vs, 0); +- vnc_write_u16(vs, 1); /* number of rects */ +- vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT); +- vnc_write_u16(vs, src_x); +- vnc_write_u16(vs, src_y); +- vnc_unlock_output(vs); +- vnc_flush(vs); +-} +- +-static void vnc_dpy_copy(DisplayChangeListener *dcl, +- int src_x, int src_y, +- int dst_x, int dst_y, int w, int h) +-{ +- VncDisplay *vd = container_of(dcl, VncDisplay, dcl); +- VncState *vs, *vn; +- uint8_t *src_row; +- uint8_t *dst_row; +- int i, x, y, pitch, inc, w_lim, s; +- int cmp_bytes; +- +- vnc_refresh_server_surface(vd); +- QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) { +- if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) { +- vs->force_update = 1; +- vnc_update_client_sync(vs, 1); +- /* vs might be free()ed here */ +- } +- } +- +- /* do bitblit op on the local surface too */ +- pitch = vnc_server_fb_stride(vd); +- src_row = vnc_server_fb_ptr(vd, src_x, src_y); +- dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y); +- y = dst_y; +- inc = 1; +- if (dst_y > src_y) { +- /* copy backwards */ +- src_row += pitch * (h-1); +- dst_row += pitch * (h-1); +- pitch = -pitch; +- y = dst_y + h - 1; +- inc = -1; +- } +- w_lim = w - (16 - (dst_x % 16)); +- if (w_lim < 0) +- w_lim = w; +- else +- w_lim = w - (w_lim % 16); +- for (i = 0; i < h; i++) { +- for (x = 0; x <= w_lim; +- x += s, src_row += cmp_bytes, dst_row += cmp_bytes) { +- if (x == w_lim) { +- if ((s = w - w_lim) == 0) +- break; +- } else if (!x) { +- s = (16 - (dst_x % 16)); +- s = MIN(s, w_lim); +- } else { +- s = 16; +- } +- cmp_bytes = s * VNC_SERVER_FB_BYTES; +- if (memcmp(src_row, dst_row, cmp_bytes) == 0) +- continue; +- memmove(dst_row, src_row, cmp_bytes); +- QTAILQ_FOREACH(vs, &vd->clients, next) { +- if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) { +- set_bit(((x + dst_x) / 16), vs->dirty[y]); +- } +- } +- } +- src_row += pitch - w * VNC_SERVER_FB_BYTES; +- dst_row += pitch - w * VNC_SERVER_FB_BYTES; +- y += inc; +- } +- +- QTAILQ_FOREACH(vs, &vd->clients, next) { +- if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) { +- vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h); +- } +- } +-} +- + static void vnc_mouse_set(DisplayChangeListener *dcl, + int x, int y, int visible) + { +@@ -873,13 +785,6 @@ static int find_and_clear_dirty_height(struct VncState *vs, + return h; + } + +-static int vnc_update_client_sync(VncState *vs, int has_dirty) +-{ +- int ret = vnc_update_client(vs, has_dirty); +- vnc_jobs_join(vs); +- return ret; +-} +- + static int vnc_update_client(VncState *vs, int has_dirty) + { + if (vs->need_update && vs->csock != -1) { +@@ -2912,7 +2817,6 @@ static void vnc_listen_websocket_read(void *opaque) + static const DisplayChangeListenerOps dcl_ops = { + .dpy_name = "vnc", + .dpy_refresh = vnc_refresh, +- .dpy_gfx_copy = vnc_dpy_copy, + .dpy_gfx_update = vnc_dpy_update, + .dpy_gfx_switch = vnc_dpy_switch, + .dpy_mouse_set = vnc_mouse_set, +-- +1.8.3.1 + diff --git a/SOURCES/kvm-fix-cirrus_vga-fix-OOB-read-case-qemu-Segmentation-f.patch b/SOURCES/kvm-fix-cirrus_vga-fix-OOB-read-case-qemu-Segmentation-f.patch new file mode 100644 index 0000000..a8641a6 --- /dev/null +++ b/SOURCES/kvm-fix-cirrus_vga-fix-OOB-read-case-qemu-Segmentation-f.patch @@ -0,0 +1,64 @@ +From d27fae125c1efd59ba3263260d41f8e054b070a2 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 21 Mar 2017 09:58:01 +0100 +Subject: [PATCH 1/7] fix :cirrus_vga fix OOB read case qemu Segmentation fault + +RH-Author: Gerd Hoffmann +Message-id: <1490090287-1503-2-git-send-email-kraxel@redhat.com> +Patchwork-id: 74419 +O-Subject: [RHEL-7.4 qemu-kvm PATCH 1/7] fix :cirrus_vga fix OOB read case qemu Segmentation fault +Bugzilla: 1430059 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +From: hangaohuai + +check the validity of parameters in cirrus_bitblt_rop_fwd_transp_xxx +and cirrus_bitblt_rop_fwd_xxx to avoid the OOB read which causes qemu Segmentation fault. + +After the fix, we will touch the assert in +cirrus_invalidate_region: +assert(off_cur_end >= off_cur); + +Signed-off-by: fangying +Signed-off-by: hangaohuai +Message-id: 20170314063919.16200-1-hangaohuai@huawei.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 215902d7b6fb50c6fc216fc74f770858278ed904) +Signed-off-by: Miroslav Rezanina +--- + hw/display/cirrus_vga_rop.h | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/hw/display/cirrus_vga_rop.h b/hw/display/cirrus_vga_rop.h +index 9c7bb09..a4f96c6 100644 +--- a/hw/display/cirrus_vga_rop.h ++++ b/hw/display/cirrus_vga_rop.h +@@ -98,6 +98,11 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, + uint8_t p; + dstpitch -= bltwidth; + srcpitch -= bltwidth; ++ ++ if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) { ++ return; ++ } ++ + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x++) { + p = *dst; +@@ -144,6 +149,11 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, + uint8_t p1, p2; + dstpitch -= bltwidth; + srcpitch -= bltwidth; ++ ++ if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) { ++ return; ++ } ++ + for (y = 0; y < bltheight; y++) { + for (x = 0; x < bltwidth; x+=2) { + p1 = *dst; +-- +1.8.3.1 + diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec index 66a2a5f..2f9a30f 100644 --- a/SPECS/qemu-kvm.spec +++ b/SPECS/qemu-kvm.spec @@ -76,7 +76,7 @@ Obsoletes: %1 < %{obsoletes_version} \ Summary: QEMU is a FAST! processor emulator Name: %{pkgname}%{?pkgsuffix} Version: 1.5.3 -Release: 126%{?dist}.5 +Release: 126%{?dist}.6 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 10 License: GPLv2+ and LGPLv2+ and BSD @@ -3432,6 +3432,20 @@ Patch1686: kvm-cirrus-fix-patterncopy-checks.patch Patch1687: kvm-Revert-cirrus-allow-zero-source-pitch-in-pattern-fil.patch # For bz#1420490 - EMBARGOED CVE-2017-2620 qemu-kvm: Qemu: display: cirrus: potential arbitrary code execution via cirrus_bitblt_cputovideo [rhel-7.3.z] Patch1688: kvm-cirrus-add-blit_is_unsafe-call-to-cirrus_bitblt_cput.patch +# For bz#1430059 - CVE-2016-9603 qemu-kvm: Qemu: cirrus: heap buffer overflow via vnc connection [rhel-7.3.z] +Patch1689: kvm-fix-cirrus_vga-fix-OOB-read-case-qemu-Segmentation-f.patch +# For bz#1430059 - CVE-2016-9603 qemu-kvm: Qemu: cirrus: heap buffer overflow via vnc connection [rhel-7.3.z] +Patch1690: kvm-cirrus-vnc-zap-bitblit-support-from-console-code.patch +# For bz#1430059 - CVE-2016-9603 qemu-kvm: Qemu: cirrus: heap buffer overflow via vnc connection [rhel-7.3.z] +Patch1691: kvm-cirrus-add-option-to-disable-blitter.patch +# For bz#1430059 - CVE-2016-9603 qemu-kvm: Qemu: cirrus: heap buffer overflow via vnc connection [rhel-7.3.z] +Patch1692: kvm-cirrus-fix-cirrus_invalidate_region.patch +# For bz#1430059 - CVE-2016-9603 qemu-kvm: Qemu: cirrus: heap buffer overflow via vnc connection [rhel-7.3.z] +Patch1693: kvm-cirrus-stop-passing-around-dst-pointers-in-the-blitt.patch +# For bz#1430059 - CVE-2016-9603 qemu-kvm: Qemu: cirrus: heap buffer overflow via vnc connection [rhel-7.3.z] +Patch1694: kvm-cirrus-stop-passing-around-src-pointers-in-the-blitt.patch +# For bz#1430059 - CVE-2016-9603 qemu-kvm: Qemu: cirrus: heap buffer overflow via vnc connection [rhel-7.3.z] +Patch1695: kvm-cirrus-fix-off-by-one-in-cirrus_bitblt_rop_bkwd_tran.patch BuildRequires: zlib-devel @@ -5300,6 +5314,13 @@ cp %{SOURCE18} pc-bios # keep "make check" happy %patch1686 -p1 %patch1687 -p1 %patch1688 -p1 +%patch1689 -p1 +%patch1690 -p1 +%patch1691 -p1 +%patch1692 -p1 +%patch1693 -p1 +%patch1694 -p1 +%patch1695 -p1 %build buildarch="%{kvm_target}-softmmu" @@ -5745,6 +5766,17 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %{_mandir}/man8/qemu-nbd.8* %changelog +* Fri Mar 24 2017 Miroslav Rezanina - 1.5.3-126.el7_3.6 +- kvm-fix-cirrus_vga-fix-OOB-read-case-qemu-Segmentation-f.patch [bz#1430059] +- kvm-cirrus-vnc-zap-bitblit-support-from-console-code.patch [bz#1430059] +- kvm-cirrus-add-option-to-disable-blitter.patch [bz#1430059] +- kvm-cirrus-fix-cirrus_invalidate_region.patch [bz#1430059] +- kvm-cirrus-stop-passing-around-dst-pointers-in-the-blitt.patch [bz#1430059] +- kvm-cirrus-stop-passing-around-src-pointers-in-the-blitt.patch [bz#1430059] +- kvm-cirrus-fix-off-by-one-in-cirrus_bitblt_rop_bkwd_tran.patch [bz#1430059] +- Resolves: bz#1430059 + (CVE-2016-9603 qemu-kvm: Qemu: cirrus: heap buffer overflow via vnc connection [rhel-7.3.z]) + * Mon Feb 13 2017 Miroslav Rezanina - 1.5.3-126.el7_3.5 - kvm-cirrus-fix-patterncopy-checks.patch [bz#1420490] - kvm-Revert-cirrus-allow-zero-source-pitch-in-pattern-fil.patch [bz#1420490]