From patchwork Fri Dec 31 19:11:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aurelien Jarno X-Patchwork-Id: 77105 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3A178B70D5 for ; Sat, 1 Jan 2011 06:16:23 +1100 (EST) Received: from localhost ([127.0.0.1]:59035 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PYkSZ-0006aw-FR for incoming@patchwork.ozlabs.org; Fri, 31 Dec 2010 14:16:19 -0500 Received: from [140.186.70.92] (port=39988 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PYkNm-00040B-PK for qemu-devel@nongnu.org; Fri, 31 Dec 2010 14:11:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PYkNl-0003a4-C0 for qemu-devel@nongnu.org; Fri, 31 Dec 2010 14:11:22 -0500 Received: from hall.aurel32.net ([88.191.126.93]:60234) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PYkNl-0003a0-6C for qemu-devel@nongnu.org; Fri, 31 Dec 2010 14:11:21 -0500 Received: from farad.aurel32.net ([82.232.2.251] helo=volta.aurel32.net) by hall.aurel32.net with esmtpsa (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1PYkNk-0001ts-MO; Fri, 31 Dec 2010 20:11:20 +0100 Received: from aurel32 by volta.aurel32.net with local (Exim 4.72) (envelope-from ) id 1PYkNj-00014n-AF; Fri, 31 Dec 2010 20:11:19 +0100 From: Aurelien Jarno To: qemu-devel@nongnu.org Date: Fri, 31 Dec 2010 20:11:18 +0100 Message-Id: <1293822678-4100-1-git-send-email-aurelien@aurel32.net> X-Mailer: git-send-email 1.7.2.3 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: Aurelien Jarno Subject: [Qemu-devel] [PATCH] cirrus_vga: fix division by 0 for color expansion rop X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Commit d85d0d3883f5a567fa2969a0396e42e0a662b3fa introduces a regression with Windows ME that leads to a division by 0 and a crash. It uses the color expansion rop with the source pitch set to 0. This is something allowed, as the manual explicitely says "When the source of color-expand data is display memory, the source pitch is ignored.". This patch fixes this regression by computing sx, sy and others variables only if they are going to be used later, that is for a plain copy ROP. It basically consists in moving code. Signed-off-by: Aurelien Jarno --- hw/cirrus_vga.c | 65 ++++++++++++++++++++++++++++--------------------------- 1 files changed, 33 insertions(+), 32 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 4f5040c..d4f2556 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -675,44 +675,45 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) { int sx, sy; int dx, dy; - int width, height; int depth; int notify = 0; - depth = s->vga.get_bpp(&s->vga) / 8; - s->vga.get_resolution(&s->vga, &width, &height); - - /* extra x, y */ - sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth; - sy = (src / ABS(s->cirrus_blt_srcpitch)); - dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth; - dy = (dst / ABS(s->cirrus_blt_dstpitch)); - - /* normalize width */ - w /= depth; - - /* if we're doing a backward copy, we have to adjust - our x/y to be the upper left corner (instead of the lower - right corner) */ - if (s->cirrus_blt_dstpitch < 0) { - sx -= (s->cirrus_blt_width / depth) - 1; - dx -= (s->cirrus_blt_width / depth) - 1; - sy -= s->cirrus_blt_height - 1; - dy -= s->cirrus_blt_height - 1; - } + /* make to sure only copy if it's a plain copy ROP */ + if (*s->cirrus_rop == cirrus_bitblt_rop_fwd_src || + *s->cirrus_rop == cirrus_bitblt_rop_bkwd_src) { + + int width, height; + + depth = s->vga.get_bpp(&s->vga) / 8; + s->vga.get_resolution(&s->vga, &width, &height); + + /* extra x, y */ + sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth; + sy = (src / ABS(s->cirrus_blt_srcpitch)); + dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth; + dy = (dst / ABS(s->cirrus_blt_dstpitch)); + + /* normalize width */ + w /= depth; + + /* if we're doing a backward copy, we have to adjust + our x/y to be the upper left corner (instead of the lower + right corner) */ + if (s->cirrus_blt_dstpitch < 0) { + sx -= (s->cirrus_blt_width / depth) - 1; + dx -= (s->cirrus_blt_width / depth) - 1; + sy -= s->cirrus_blt_height - 1; + dy -= s->cirrus_blt_height - 1; + } - /* are we in the visible portion of memory? */ - if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 && - (sx + w) <= width && (sy + h) <= height && - (dx + w) <= width && (dy + h) <= height) { - notify = 1; + /* are we in the visible portion of memory? */ + if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 && + (sx + w) <= width && (sy + h) <= height && + (dx + w) <= width && (dy + h) <= height) { + notify = 1; + } } - /* make to sure only copy if it's a plain copy ROP */ - if (*s->cirrus_rop != cirrus_bitblt_rop_fwd_src && - *s->cirrus_rop != cirrus_bitblt_rop_bkwd_src) - notify = 0; - /* we have to flush all pending changes so that the copy is generated at the appropriate moment in time */ if (notify)