Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:Update
qemu-linux-user
0205-cirrus-stop-passing-around-src-poin.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0205-cirrus-stop-passing-around-src-poin.patch of Package qemu-linux-user
From: Gerd Hoffmann <kraxel@redhat.com> Date: Wed, 15 Mar 2017 14:28:07 +0100 Subject: cirrus: stop passing around src pointers in the blitter 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 <kraxel@redhat.com> Message-id: 1489584487-3489-1-git-send-email-kraxel@redhat.com (cherry picked from commit ffaf857778286ca54e3804432a2369a279e73aa7) [BR: BSC#1035406 CVE-2017-7980] Signed-off-by: Bruce Rogers <brogers@suse.com> --- 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 4761bfca3a39605913d74f518025..5963e8e34cf0eec046bec5b7d6fd 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -177,7 +177,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, @@ -320,7 +320,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) { @@ -332,6 +332,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" @@ -674,10 +713,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)) { @@ -698,15 +737,13 @@ 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, @@ -743,7 +780,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) @@ -793,7 +830,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); @@ -836,7 +873,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); @@ -844,7 +881,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 1aa778d3e8114a42e0bd68ca8ad2..c61a67735341239faf2285989d27 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) { @@ -92,19 +92,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) { @@ -113,19 +113,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, @@ -142,19 +142,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, @@ -166,19 +166,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, @@ -195,19 +195,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, @@ -219,12 +219,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 bc92f0e0e79f7a26f6ce0007ade7..b86bcd6e09a4e0551e8769b5fb9a 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)) {
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor