From patchwork Wed May 12 18:11:17 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 99073 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o4CI8YI5026157 for ; Wed, 12 May 2010 18:08:34 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751562Ab0ELSIc (ORCPT ); Wed, 12 May 2010 14:08:32 -0400 Received: from smtp.citrix.com ([66.165.176.89]:58411 "EHLO SMTP.CITRIX.COM" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750752Ab0ELSIb (ORCPT ); Wed, 12 May 2010 14:08:31 -0400 X-IronPort-AV: E=Sophos;i="4.53,216,1272859200"; d="scan'208";a="8446334" Received: from ftlpmailmx02.citrite.net ([10.9.154.224]) by FTLPIPO01.CITRIX.COM with ESMTP/TLS/RC4-MD5; 12 May 2010 14:08:29 -0400 Received: from LONPMAILMX01.citrite.net (10.30.224.162) by FTLPMAILMX02.citrite.net (10.9.154.224) with Microsoft SMTP Server (TLS) id 8.2.254.0; Wed, 12 May 2010 14:08:29 -0400 Received: from kaball.uk.xensource.com (10.80.2.59) by smtprelay.citrix.com (10.30.224.162) with Microsoft SMTP Server id 8.2.254.0; Wed, 12 May 2010 19:08:28 +0100 Date: Wed, 12 May 2010 19:11:17 +0100 From: Stefano Stabellini X-X-Sender: sstabellini@kaball-desktop To: Jamie Lokier CC: Stefano Stabellini , Avi Kivity , Brian Kress , Michael Tokarev , qemu-devel , KVM list Subject: Re: [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus In-Reply-To: <20100512170702.GE19314@shareable.org> Message-ID: References: <4BE32178.2090103@msgid.tls.msk.ru> <4BE7B8C1.9060807@redhat.com> <4BE7C0A5.3090909@redhat.com> <4BEAA0CC.4090906@redhat.com> <4BEABABC.6080305@redhat.com> <4BEAD232.2040700@redhat.com> <20100512170702.GE19314@shareable.org> User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 12 May 2010 18:08:34 +0000 (UTC) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 9f61a01..a7f0d3c 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -676,15 +676,17 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) int sx, sy; int dx, dy; int width, height; + uint32_t start_addr, line_offset, line_compare; int depth; int notify = 0; depth = s->vga.get_bpp(&s->vga) / 8; s->vga.get_resolution(&s->vga, &width, &height); + s->vga.get_offsets(&s->vga, &line_offset, &start_addr, &line_compare); /* extra x, y */ - sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth; - sy = (src / ABS(s->cirrus_blt_srcpitch)); + sx = (src % line_offset) / depth; + sy = (src / line_offset); dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth; dy = (dst / ABS(s->cirrus_blt_dstpitch)); @@ -725,18 +727,23 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, s->cirrus_blt_width, s->cirrus_blt_height); - if (notify) - qemu_console_copy(s->vga.ds, - sx, sy, dx, dy, - s->cirrus_blt_width / depth, - s->cirrus_blt_height); - - /* we don't have to notify the display that this portion has - changed since qemu_console_copy implies this */ - - cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, - s->cirrus_blt_dstpitch, s->cirrus_blt_width, - s->cirrus_blt_height); + if (ABS(s->cirrus_blt_dstpitch) != line_offset || + ABS(s->cirrus_blt_srcpitch) != line_offset) { + /* this is not going to happen very often */ + vga_hw_invalidate(); + } else { + if (notify) + /* we don't have to notify the display that this portion has + changed since qemu_console_copy implies this */ + qemu_console_copy(s->vga.ds, + sx, sy, dx, dy, + s->cirrus_blt_width / depth, + s->cirrus_blt_height); + else + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, + s->cirrus_blt_dstpitch, s->cirrus_blt_width, + s->cirrus_blt_height); + } } static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) diff --git a/hw/cirrus_vga_rop.h b/hw/cirrus_vga_rop.h index 39a7b72..80f135b 100644 --- a/hw/cirrus_vga_rop.h +++ b/hw/cirrus_vga_rop.h @@ -32,10 +32,10 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s, dstpitch -= bltwidth; srcpitch -= bltwidth; - if (dstpitch < 0 || srcpitch < 0) { - /* is 0 valid? srcpitch == 0 could be useful */ + if (dstpitch < 0) return; - } + if (srcpitch < 0) + srcpitch = 0; for (y = 0; y < bltheight; y++) { for (x = 0; x < bltwidth; x++) { @@ -57,6 +57,12 @@ glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s, int x,y; dstpitch += bltwidth; srcpitch += bltwidth; + + if (dstpitch > 0) + return; + if (srcpitch > 0) + srcpitch = 0; + for (y = 0; y < bltheight; y++) { for (x = 0; x < bltwidth; x++) { ROP_OP(*dst, *src); @@ -78,6 +84,12 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, uint8_t p; dstpitch -= bltwidth; srcpitch -= bltwidth; + + if (dstpitch < 0) + return; + if (srcpitch < 0) + srcpitch = 0; + for (y = 0; y < bltheight; y++) { for (x = 0; x < bltwidth; x++) { p = *dst; @@ -101,6 +113,12 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, uint8_t p; dstpitch += bltwidth; srcpitch += bltwidth; + + if (dstpitch > 0) + return; + if (srcpitch > 0) + srcpitch = 0; + for (y = 0; y < bltheight; y++) { for (x = 0; x < bltwidth; x++) { p = *dst; @@ -124,6 +142,12 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, uint8_t p1, p2; dstpitch -= bltwidth; srcpitch -= bltwidth; + + if (dstpitch < 0) + return; + if (srcpitch < 0) + srcpitch = 0; + for (y = 0; y < bltheight; y++) { for (x = 0; x < bltwidth; x+=2) { p1 = *dst; @@ -152,6 +176,12 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, uint8_t p1, p2; dstpitch += bltwidth; srcpitch += bltwidth; + + if (dstpitch > 0) + return; + if (srcpitch > 0) + srcpitch = 0; + for (y = 0; y < bltheight; y++) { for (x = 0; x < bltwidth; x+=2) { p1 = *(dst-1);