From nobody Sun Apr 28 13:05:41 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1489657205994154.4536468559695; Thu, 16 Mar 2017 02:40:05 -0700 (PDT) Received: from localhost ([::1]:41927 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRt6-00039N-QG for importer@patchew.org; Thu, 16 Mar 2017 05:40:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50179) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRkH-00049H-9w for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:30:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1coRkF-0003j4-OQ for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:30:57 -0400 Received: from mx1.redhat.com ([209.132.183.28]:20741) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1coRkF-0003im-IQ for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:30:55 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8393A3DBF3; Thu, 16 Mar 2017 09:30:55 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-116-71.ams2.redhat.com [10.36.116.71]) by smtp.corp.redhat.com (Postfix) with ESMTP id 74B4C627D9; Thu, 16 Mar 2017 09:30:53 +0000 (UTC) Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 497FC80BD1; Thu, 16 Mar 2017 10:30:51 +0100 (CET) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8393A3DBF3 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=kraxel@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 8393A3DBF3 From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 16 Mar 2017 10:30:36 +0100 Message-Id: <1489656642-12925-2-git-send-email-kraxel@redhat.com> In-Reply-To: <1489656642-12925-1-git-send-email-kraxel@redhat.com> References: <1489656642-12925-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 16 Mar 2017 09:30:55 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL for-2.9 1/7] fix :cirrus_vga fix OOB read case qemu Segmentation fault X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: fangying , hangaohuai , Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 Segme= ntation fault. After the fix, we will touch the assert in cirrus_invalidate_region: assert(off_cur_end >=3D off_cur); Signed-off-by: fangying Signed-off-by: hangaohuai Message-id: 20170314063919.16200-1-hangaohuai@huawei.com Signed-off-by: Gerd Hoffmann --- 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 0925a00..b7447f8 100644 --- a/hw/display/cirrus_vga_rop.h +++ b/hw/display/cirrus_vga_rop.h @@ -97,6 +97,11 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(C= irrusVGAState *s, uint8_t p; dstpitch -=3D bltwidth; srcpitch -=3D bltwidth; + + if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) { + return; + } + for (y =3D 0; y < bltheight; y++) { for (x =3D 0; x < bltwidth; x++) { p =3D *dst; @@ -143,6 +148,11 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16= )(CirrusVGAState *s, uint8_t p1, p2; dstpitch -=3D bltwidth; srcpitch -=3D bltwidth; + + if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) { + return; + } + for (y =3D 0; y < bltheight; y++) { for (x =3D 0; x < bltwidth; x+=3D2) { p1 =3D *dst; --=20 1.8.3.1 From nobody Sun Apr 28 13:05:41 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1489656945830302.51762415097005; Thu, 16 Mar 2017 02:35:45 -0700 (PDT) Received: from localhost ([::1]:41853 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRot-0007NQ-Sy for importer@patchew.org; Thu, 16 Mar 2017 05:35:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50249) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRkM-0004CP-H0 for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:31:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1coRkI-0003ki-2E for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:31:02 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55440) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1coRkH-0003jk-IN for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:30:57 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 986499D4F2 for ; Thu, 16 Mar 2017 09:30:57 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-116-71.ams2.redhat.com [10.36.116.71]) by smtp.corp.redhat.com (Postfix) with ESMTP id 765DD5C3FD; Thu, 16 Mar 2017 09:30:53 +0000 (UTC) Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 5F40380BE3; Thu, 16 Mar 2017 10:30:51 +0100 (CET) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 986499D4F2 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=kraxel@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 986499D4F2 From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 16 Mar 2017 10:30:37 +0100 Message-Id: <1489656642-12925-3-git-send-email-kraxel@redhat.com> In-Reply-To: <1489656642-12925-1-git-send-email-kraxel@redhat.com> References: <1489656642-12925-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 16 Mar 2017 09:30:57 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL for-2.9 2/7] cirrus/vnc: zap bitblit support from console code. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 --- hw/display/cirrus_vga.c | 12 ++---- include/ui/console.h | 7 ---- ui/console.c | 28 -------------- ui/vnc.c | 100 --------------------------------------------= ---- 4 files changed, 3 insertions(+), 144 deletions(-) diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index b9e7cb1..c90a4a3 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -796,21 +796,15 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst,= int src, int w, int h) } } =20 - /* 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); =20 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); } =20 /* 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 ac2895c..d759338 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -189,9 +189,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); bool (*dpy_gfx_check_format)(DisplayChangeListener *dcl, pixman_format_code_t format); =20 @@ -277,8 +274,6 @@ int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info); 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); @@ -411,8 +406,6 @@ void qemu_console_set_window_id(QemuConsole *con, int w= indow_id); =20 void console_select(unsigned int index); 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); =20 /* console-gl.c */ diff --git a/ui/console.c b/ui/console.c index d1ff750..4c70d8b 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1586,27 +1586,6 @@ static void dpy_refresh(DisplayState *s) } } =20 -void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y, - int dst_x, int dst_y, int w, int h) -{ - DisplayState *s =3D con->ds; - DisplayChangeListener *dcl; - - if (!qemu_console_is_visible(con)) { - return; - } - QLIST_FOREACH(dcl, &s->listeners, next) { - if (con !=3D (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 =3D con->ds; @@ -2138,13 +2117,6 @@ void qemu_console_resize(QemuConsole *s, int width, = int height) dpy_gfx_replace_surface(s, surface); } =20 -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 =3D=3D 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 51f4b30..8bfb1e0 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -894,105 +894,6 @@ int vnc_send_framebuffer_update(VncState *vs, int x, = int y, int w, int h) return n; } =20 -static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int ds= t_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 =3D 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; - - if (!vd->server) { - /* no client connected */ - return; - } - - vnc_refresh_server_surface(vd); - QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) { - if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) { - vs->force_update =3D 1; - vnc_update_client(vs, 1, true); - /* vs might be free()ed here */ - } - } - - if (!vd->server) { - /* no client connected */ - return; - } - /* do bitblit op on the local surface too */ - pitch =3D vnc_server_fb_stride(vd); - src_row =3D vnc_server_fb_ptr(vd, src_x, src_y); - dst_row =3D vnc_server_fb_ptr(vd, dst_x, dst_y); - y =3D dst_y; - inc =3D 1; - if (dst_y > src_y) { - /* copy backwards */ - src_row +=3D pitch * (h-1); - dst_row +=3D pitch * (h-1); - pitch =3D -pitch; - y =3D dst_y + h - 1; - inc =3D -1; - } - w_lim =3D w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PE= R_BIT)); - if (w_lim < 0) { - w_lim =3D w; - } else { - w_lim =3D w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT); - } - for (i =3D 0; i < h; i++) { - for (x =3D 0; x <=3D w_lim; - x +=3D s, src_row +=3D cmp_bytes, dst_row +=3D cmp_bytes) { - if (x =3D=3D w_lim) { - if ((s =3D w - w_lim) =3D=3D 0) - break; - } else if (!x) { - s =3D (VNC_DIRTY_PIXELS_PER_BIT - - (dst_x % VNC_DIRTY_PIXELS_PER_BIT)); - s =3D MIN(s, w_lim); - } else { - s =3D VNC_DIRTY_PIXELS_PER_BIT; - } - cmp_bytes =3D s * VNC_SERVER_FB_BYTES; - if (memcmp(src_row, dst_row, cmp_bytes) =3D=3D 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) / VNC_DIRTY_PIXELS_PER_BIT), - vs->dirty[y]); - } - } - } - src_row +=3D pitch - w * VNC_SERVER_FB_BYTES; - dst_row +=3D pitch - w * VNC_SERVER_FB_BYTES; - y +=3D 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) { @@ -3120,7 +3021,6 @@ static gboolean vnc_listen_io(QIOChannel *ioc, static const DisplayChangeListenerOps dcl_ops =3D { .dpy_name =3D "vnc", .dpy_refresh =3D vnc_refresh, - .dpy_gfx_copy =3D vnc_dpy_copy, .dpy_gfx_update =3D vnc_dpy_update, .dpy_gfx_switch =3D vnc_dpy_switch, .dpy_gfx_check_format =3D qemu_pixman_check_format, --=20 1.8.3.1 From nobody Sun Apr 28 13:05:41 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1489657305009764.7498842922183; Thu, 16 Mar 2017 02:41:45 -0700 (PDT) Received: from localhost ([::1]:42010 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRuh-0004Xc-Kg for importer@patchew.org; Thu, 16 Mar 2017 05:41:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50171) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRkG-00048r-Pm for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:30:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1coRkF-0003jF-PT for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:30:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43542) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1coRkF-0003ii-Iw for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:30:55 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 577643DBE9 for ; Thu, 16 Mar 2017 09:30:55 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-116-71.ams2.redhat.com [10.36.116.71]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7018F6031D; Thu, 16 Mar 2017 09:30:53 +0000 (UTC) Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 7293980BF9; Thu, 16 Mar 2017 10:30:51 +0100 (CET) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 577643DBE9 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=kraxel@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 577643DBE9 From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 16 Mar 2017 10:30:38 +0100 Message-Id: <1489656642-12925-4-git-send-email-kraxel@redhat.com> In-Reply-To: <1489656642-12925-1-git-send-email-kraxel@redhat.com> References: <1489656642-12925-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 16 Mar 2017 09:30:55 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL for-2.9 3/7] cirrus: switch to 4 MB video memory by default X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Quoting cirrus source code: Follow real hardware, cirrus card emulated has 4 MB video memory. Also accept 8 MB/16 MB for backward compatibility. So just use 4MB by default. We decided to leave that at 8MB by default a while ago, for live migration compatibility reasons. But we have compat properties to handle that, so that isn't a compeling reason. This also removes some sanity check inconsistencies in the cirrus code. Some places check against the allocated video memory, some places check against the 4MB physical hardware has. Guest code can trigger asserts because of that. Signed-off-by: Gerd Hoffmann Message-id: 1489494514-15606-1-git-send-email-kraxel@redhat.com --- hw/display/cirrus_vga.c | 4 ++-- include/hw/compat.h | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index c90a4a3..6ffe64f 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -3023,7 +3023,7 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev= , Error **errp) =20 static Property isa_cirrus_vga_properties[] =3D { DEFINE_PROP_UINT32("vgamem_mb", struct ISACirrusVGAState, - cirrus_vga.vga.vram_size_mb, 8), + cirrus_vga.vga.vram_size_mb, 4), DEFINE_PROP_END_OF_LIST(), }; =20 @@ -3092,7 +3092,7 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Er= ror **errp) =20 static Property pci_vga_cirrus_properties[] =3D { DEFINE_PROP_UINT32("vgamem_mb", struct PCICirrusVGAState, - cirrus_vga.vga.vram_size_mb, 8), + cirrus_vga.vga.vram_size_mb, 4), DEFINE_PROP_END_OF_LIST(), }; =20 diff --git a/include/hw/compat.h b/include/hw/compat.h index b7db438..b7e0e9f 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -18,6 +18,14 @@ .driver =3D "pci-bridge",\ .property =3D "shpc",\ .value =3D "on",\ + },{\ + .driver =3D "cirrus-vga",\ + .property =3D "vgamem_mb",\ + .value =3D "8",\ + },{\ + .driver =3D "isa-cirrus-vga",\ + .property =3D "vgamem_mb",\ + .value =3D "8",\ }, =20 #define HW_COMPAT_2_7 \ --=20 1.8.3.1 From nobody Sun Apr 28 13:05:41 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 148965709910367.85283646791697; Thu, 16 Mar 2017 02:38:19 -0700 (PDT) Received: from localhost ([::1]:41917 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRrN-0001dX-V4 for importer@patchew.org; Thu, 16 Mar 2017 05:38:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50173) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRkH-000498-5K for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:30:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1coRkF-0003jM-QY for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:30:57 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59936) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1coRkF-0003ij-IK for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:30:55 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7551964D8A for ; Thu, 16 Mar 2017 09:30:55 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-116-71.ams2.redhat.com [10.36.116.71]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7892E627DE; Thu, 16 Mar 2017 09:30:53 +0000 (UTC) Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 81BCE805BC; Thu, 16 Mar 2017 10:30:51 +0100 (CET) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 7551964D8A Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=kraxel@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 7551964D8A From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 16 Mar 2017 10:30:39 +0100 Message-Id: <1489656642-12925-5-git-send-email-kraxel@redhat.com> In-Reply-To: <1489656642-12925-1-git-send-email-kraxel@redhat.com> References: <1489656642-12925-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 16 Mar 2017 09:30:55 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL for-2.9 4/7] cirrus: add option to disable blitter X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 --- 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 6ffe64f..326d511 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -205,6 +205,7 @@ typedef struct CirrusVGAState { uint32_t cirrus_bank_base[2]; uint32_t cirrus_bank_limit[2]; uint8_t cirrus_hidden_palette[48]; + bool enable_blitter; int cirrus_blt_pixelwidth; int cirrus_blt_width; int cirrus_blt_height; @@ -960,6 +961,10 @@ static void cirrus_bitblt_start(CirrusVGAState * s) { uint8_t blt_rop; =20 + if (!s->enable_blitter) { + goto bitblt_ignore; + } + s->vga.gr[0x31] |=3D CIRRUS_BLT_BUSY; =20 s->cirrus_blt_width =3D (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1; @@ -3024,6 +3029,8 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev= , Error **errp) static Property isa_cirrus_vga_properties[] =3D { DEFINE_PROP_UINT32("vgamem_mb", struct ISACirrusVGAState, cirrus_vga.vga.vram_size_mb, 4), + DEFINE_PROP_BOOL("blitter", struct ISACirrusVGAState, + cirrus_vga.enable_blitter, true), DEFINE_PROP_END_OF_LIST(), }; =20 @@ -3093,6 +3100,8 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Er= ror **errp) static Property pci_vga_cirrus_properties[] =3D { DEFINE_PROP_UINT32("vgamem_mb", struct PCICirrusVGAState, cirrus_vga.vga.vram_size_mb, 4), + DEFINE_PROP_BOOL("blitter", struct PCICirrusVGAState, + cirrus_vga.enable_blitter, true), DEFINE_PROP_END_OF_LIST(), }; =20 --=20 1.8.3.1 From nobody Sun Apr 28 13:05:41 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1489656792012741.8967977684337; Thu, 16 Mar 2017 02:33:12 -0700 (PDT) Received: from localhost ([::1]:41846 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRmQ-00051R-Oi for importer@patchew.org; Thu, 16 Mar 2017 05:33:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50252) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRkM-0004CR-Hn for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:31:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1coRkI-0003l1-HZ for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:31:02 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34782) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1coRkI-0003k2-44 for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:30:58 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2A3B2C0092CB for ; Thu, 16 Mar 2017 09:30:58 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-116-71.ams2.redhat.com [10.36.116.71]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2D2F118978; Thu, 16 Mar 2017 09:30:56 +0000 (UTC) Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 946D280BFD; Thu, 16 Mar 2017 10:30:51 +0100 (CET) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 2A3B2C0092CB Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=kraxel@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 2A3B2C0092CB From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 16 Mar 2017 10:30:40 +0100 Message-Id: <1489656642-12925-6-git-send-email-kraxel@redhat.com> In-Reply-To: <1489656642-12925-1-git-send-email-kraxel@redhat.com> References: <1489656642-12925-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Thu, 16 Mar 2017 09:30:58 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL for-2.9 5/7] cirrus: fix cirrus_invalidate_region X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" off_cur_end is exclusive, so off_cur_end =3D=3D 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 --- 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 326d511..a9f6d5b 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -667,11 +667,11 @@ static void cirrus_invalidate_region(CirrusVGAState *= s, int off_begin, } =20 for (y =3D 0; y < lines; y++) { - off_cur =3D off_begin; - off_cur_end =3D (off_cur + bytesperline) & s->cirrus_addr_mask; + off_cur =3D off_begin; + off_cur_end =3D ((off_cur + bytesperline - 1) & s->cirrus_addr_mas= k) + 1; assert(off_cur_end >=3D off_cur); memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_c= ur); - off_begin +=3D off_pitch; + off_begin +=3D off_pitch; } } =20 --=20 1.8.3.1 From nobody Sun Apr 28 13:05:41 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1489657427395591.103860610927; Thu, 16 Mar 2017 02:43:47 -0700 (PDT) Received: from localhost ([::1]:42100 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRwg-0005jA-2O for importer@patchew.org; Thu, 16 Mar 2017 05:43:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50233) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRkK-0004Ai-9E for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:31:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1coRkH-0003k6-MR for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:31:00 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59964) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1coRkH-0003jb-Bt for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:30:57 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5C51A64D8A for ; Thu, 16 Mar 2017 09:30:57 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-116-71.ams2.redhat.com [10.36.116.71]) by smtp.corp.redhat.com (Postfix) with ESMTP id 313AA60319; Thu, 16 Mar 2017 09:30:56 +0000 (UTC) Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id AA9A080BFF; Thu, 16 Mar 2017 10:30:51 +0100 (CET) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 5C51A64D8A Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=kraxel@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 5C51A64D8A From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 16 Mar 2017 10:30:41 +0100 Message-Id: <1489656642-12925-7-git-send-email-kraxel@redhat.com> In-Reply-To: <1489656642-12925-1-git-send-email-kraxel@redhat.com> References: <1489656642-12925-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 16 Mar 2017 09:30:57 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL for-2.9 6/7] cirrus: stop passing around dst pointers in the blitter X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 --- 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 a9f6d5b..9ae1d4b 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -178,11 +178,12 @@ =20 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); =20 typedef struct CirrusVGAState { VGACommonState vga; @@ -321,14 +322,14 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, = bool dst_only) } =20 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) { } =20 static void cirrus_bitblt_fill_nop(CirrusVGAState *s, - uint8_t *dst, + uint32_t dstaddr, int dstpitch, int bltwidth,int bltheigh= t) { } @@ -678,11 +679,8 @@ static void cirrus_invalidate_region(CirrusVGAState * = s, int off_begin, static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videos= rc) { uint32_t patternsize; - uint8_t *dst; uint8_t *src; =20 - dst =3D s->vga.vram_ptr + s->cirrus_blt_dstaddr; - if (videosrc) { switch (s->vga.get_bpp(&s->vga)) { case 8: @@ -711,7 +709,7 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGASt= ate *s, bool videosrc) return 0; } =20 - (*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, @@ -730,7 +728,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, i= nt blt_rop) return 0; } rop_func =3D cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwid= th - 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, @@ -797,7 +795,7 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, i= nt src, int w, int h) } } =20 - (*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); @@ -848,7 +846,7 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAStat= e * s) } else { /* at least one scan line */ do { - (*s->cirrus_rop)(s, s->vga.vram_ptr + s->cirrus_blt_dstadd= r, + (*s->cirrus_rop)(s, s->cirrus_blt_dstaddr, s->cirrus_bltbuf, 0, 0, s->cirrus_blt_wi= dth, 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 b7447f8..1aa778d 100644 --- a/hw/display/cirrus_vga_rop.h +++ b/hw/display/cirrus_vga_rop.h @@ -22,31 +22,65 @@ * THE SOFTWARE. */ =20 -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 =3D &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask]; *dst =3D ROP_FN(*dst, src); } =20 -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 =3D &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask]; + uint8_t pixel =3D ROP_FN(*dst, src); + if (pixel !=3D transp) { + *dst =3D pixel; + } +} + +static inline void glue(rop_16_, ROP_NAME)(CirrusVGAState *s, + uint32_t dstaddr, uint16_t src) +{ + uint16_t *dst =3D (uint16_t *) + (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]); *dst =3D ROP_FN(*dst, src); } =20 -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 s= rc, + uint16_t transp) +{ + uint16_t *dst =3D (uint16_t *) + (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]); + uint16_t pixel =3D ROP_FN(*dst, src); + if (pixel !=3D transp) { + *dst =3D pixel; + } +} + +static inline void glue(rop_32_, ROP_NAME)(CirrusVGAState *s, + uint32_t dstaddr, uint32_t src) { + uint32_t *dst =3D (uint32_t *) + (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~3]); *dst =3D ROP_FN(*dst, src); } =20 -#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 =20 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 -=3D bltwidth; @@ -58,43 +92,47 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *= s, =20 for (y =3D 0; y < bltheight; y++) { for (x =3D 0; x < bltwidth; x++) { - ROP_OP(dst, *src); - dst++; + ROP_OP(s, dstaddr, *src); + dstaddr++; src++; } - dst +=3D dstpitch; + dstaddr +=3D dstpitch; src +=3D srcpitch; } } =20 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 +=3D bltwidth; srcpitch +=3D bltwidth; for (y =3D 0; y < bltheight; y++) { for (x =3D 0; x < bltwidth; x++) { - ROP_OP(dst, *src); - dst--; + ROP_OP(s, dstaddr, *src); + dstaddr--; src--; } - dst +=3D dstpitch; + dstaddr +=3D dstpitch; src +=3D srcpitch; } } =20 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 =3D s->vga.gr[0x34]; dstpitch -=3D bltwidth; srcpitch -=3D bltwidth; =20 @@ -104,48 +142,50 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8= )(CirrusVGAState *s, =20 for (y =3D 0; y < bltheight; y++) { for (x =3D 0; x < bltwidth; x++) { - p =3D *dst; - ROP_OP(&p, *src); - if (p !=3D s->vga.gr[0x34]) *dst =3D p; - dst++; + ROP_OP_TR(s, dstaddr, *src, transp); + dstaddr++; src++; } - dst +=3D dstpitch; + dstaddr +=3D dstpitch; src +=3D srcpitch; } } =20 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 =3D s->vga.gr[0x34]; dstpitch +=3D bltwidth; srcpitch +=3D bltwidth; for (y =3D 0; y < bltheight; y++) { for (x =3D 0; x < bltwidth; x++) { - p =3D *dst; - ROP_OP(&p, *src); - if (p !=3D s->vga.gr[0x34]) *dst =3D p; - dst--; + ROP_OP_TR(s, dstaddr, *src, transp); + dstaddr--; src--; } - dst +=3D dstpitch; + dstaddr +=3D dstpitch; src +=3D srcpitch; } } =20 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 =3D s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8; dstpitch -=3D bltwidth; srcpitch -=3D bltwidth; =20 @@ -155,46 +195,35 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_1= 6)(CirrusVGAState *s, =20 for (y =3D 0; y < bltheight; y++) { for (x =3D 0; x < bltwidth; x+=3D2) { - p1 =3D *dst; - p2 =3D *(dst+1); - ROP_OP(&p1, *src); - ROP_OP(&p2, *(src + 1)); - if ((p1 !=3D s->vga.gr[0x34]) || (p2 !=3D s->vga.gr[0x35])) { - *dst =3D p1; - *(dst+1) =3D p2; - } - dst+=3D2; - src+=3D2; + ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp); + dstaddr +=3D 2; + src +=3D 2; } - dst +=3D dstpitch; + dstaddr +=3D dstpitch; src +=3D srcpitch; } } =20 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 *sr= c, + int dstpitch, + int srcpitch, + int bltwidth, + int bltheight) { int x,y; - uint8_t p1, p2; + uint16_t transp =3D s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8; dstpitch +=3D bltwidth; srcpitch +=3D bltwidth; for (y =3D 0; y < bltheight; y++) { for (x =3D 0; x < bltwidth; x+=3D2) { - p1 =3D *(dst-1); - p2 =3D *dst; - ROP_OP(&p1, *(src - 1)); - ROP_OP(&p2, *src); - if ((p1 !=3D s->vga.gr[0x34]) || (p2 !=3D s->vga.gr[0x35])) { - *(dst-1) =3D p1; - *dst =3D p2; - } - dst-=3D2; - src-=3D2; + ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp); + dstaddr -=3D 2; + src -=3D 2; } - dst +=3D dstpitch; + dstaddr +=3D dstpitch; src +=3D 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 @@ */ =20 #if DEPTH =3D=3D 8 -#define PUTPIXEL() ROP_OP(&d[0], col) +#define PUTPIXEL(s, a, c) ROP_OP(s, a, c) #elif DEPTH =3D=3D 16 -#define PUTPIXEL() ROP_OP_16((uint16_t *)&d[0], col) +#define PUTPIXEL(s, a, c) ROP_OP_16(s, a, c) #elif DEPTH =3D=3D 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 =3D=3D 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 =20 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 =3D s->cirrus_blt_srcaddr & 7; for(y =3D 0; y < bltheight; y++) { pattern_x =3D skipleft; - d =3D dst + skipleft; + addr =3D dstaddr + skipleft; src1 =3D src + pattern_y * pattern_pitch; for (x =3D skipleft; x < bltwidth; x +=3D (DEPTH / 8)) { #if DEPTH =3D=3D 8 @@ -82,23 +84,23 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) col =3D ((uint32_t *)(src1 + pattern_x))[0]; pattern_x =3D (pattern_x + 4) & 31; #endif - PUTPIXEL(); - d +=3D (DEPTH / 8); + PUTPIXEL(s, addr, col); + addr +=3D (DEPTH / 8); } pattern_y =3D (pattern_y + 1) & 7; - dst +=3D dstpitch; + dstaddr +=3D dstpitch; } } =20 /* 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 =3D 0; y < bltheight; y++) { bitmask =3D 0x80 >> srcskipleft; bits =3D *src++ ^ bits_xor; - d =3D dst + dstskipleft; + addr =3D dstaddr + dstskipleft; for (x =3D dstskipleft; x < bltwidth; x +=3D (DEPTH / 8)) { if ((bitmask & 0xff) =3D=3D 0) { bitmask =3D 0x80; @@ -131,24 +133,24 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME),= _),DEPTH) } index =3D (bits & bitmask); if (index) { - PUTPIXEL(); + PUTPIXEL(s, addr, col); } - d +=3D (DEPTH / 8); + addr +=3D (DEPTH / 8); bitmask >>=3D 1; } - dst +=3D dstpitch; + dstaddr +=3D dstpitch; } } =20 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), _),DEP= TH) for(y =3D 0; y < bltheight; y++) { bitmask =3D 0x80 >> srcskipleft; bits =3D *src++; - d =3D dst + dstskipleft; + addr =3D dstaddr + dstskipleft; for (x =3D dstskipleft; x < bltwidth; x +=3D (DEPTH / 8)) { if ((bitmask & 0xff) =3D=3D 0) { bitmask =3D 0x80; bits =3D *src++; } col =3D colors[!!(bits & bitmask)]; - PUTPIXEL(); - d +=3D (DEPTH / 8); + PUTPIXEL(s, addr, col); + addr +=3D (DEPTH / 8); bitmask >>=3D 1; } - dst +=3D dstpitch; + dstaddr +=3D dstpitch; } } =20 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_, RO= P_NAME), _),DEPTH) for(y =3D 0; y < bltheight; y++) { bits =3D src[pattern_y] ^ bits_xor; bitpos =3D 7 - srcskipleft; - d =3D dst + dstskipleft; + addr =3D dstaddr + dstskipleft; for (x =3D dstskipleft; x < bltwidth; x +=3D (DEPTH / 8)) { if ((bits >> bitpos) & 1) { - PUTPIXEL(); + PUTPIXEL(s, addr, col); } - d +=3D (DEPTH / 8); + addr +=3D (DEPTH / 8); bitpos =3D (bitpos - 1) & 7; } pattern_y =3D (pattern_y + 1) & 7; - dst +=3D dstpitch; + dstaddr +=3D dstpitch; } } =20 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 =3D 0; y < bltheight; y++) { bits =3D src[pattern_y]; bitpos =3D 7 - srcskipleft; - d =3D dst + dstskipleft; + addr =3D dstaddr + dstskipleft; for (x =3D dstskipleft; x < bltwidth; x +=3D (DEPTH / 8)) { col =3D colors[(bits >> bitpos) & 1]; - PUTPIXEL(); - d +=3D (DEPTH / 8); + PUTPIXEL(s, addr, col); + addr +=3D (DEPTH / 8); bitpos =3D (bitpos - 1) & 7; } pattern_y =3D (pattern_y + 1) & 7; - dst +=3D dstpitch; + dstaddr +=3D dstpitch; } } =20 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; =20 col =3D s->cirrus_blt_fgcol; =20 - d1 =3D dst; for(y =3D 0; y < height; y++) { - d =3D d1; + addr =3D dstaddr; for(x =3D 0; x < width; x +=3D (DEPTH / 8)) { - PUTPIXEL(); - d +=3D (DEPTH / 8); + PUTPIXEL(s, addr, col); + addr +=3D (DEPTH / 8); } - d1 +=3D dst_pitch; + dstaddr +=3D dst_pitch; } } =20 --=20 1.8.3.1 From nobody Sun Apr 28 13:05:41 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1489657498803518.282899177737; Thu, 16 Mar 2017 02:44:58 -0700 (PDT) Received: from localhost ([::1]:42104 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRxp-0006I0-IG for importer@patchew.org; Thu, 16 Mar 2017 05:44:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50248) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coRkM-0004CO-Gx for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:31:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1coRkI-0003kp-3K for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:31:02 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40792) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1coRkH-0003jm-KE for qemu-devel@nongnu.org; Thu, 16 Mar 2017 05:30:57 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A78507F0A3 for ; Thu, 16 Mar 2017 09:30:57 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-116-71.ams2.redhat.com [10.36.116.71]) by smtp.corp.redhat.com (Postfix) with ESMTP id 437276031D; Thu, 16 Mar 2017 09:30:56 +0000 (UTC) Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id BC73180BFA; Thu, 16 Mar 2017 10:30:51 +0100 (CET) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A78507F0A3 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=kraxel@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com A78507F0A3 From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 16 Mar 2017 10:30:42 +0100 Message-Id: <1489656642-12925-8-git-send-email-kraxel@redhat.com> In-Reply-To: <1489656642-12925-1-git-send-email-kraxel@redhat.com> References: <1489656642-12925-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Thu, 16 Mar 2017 09:30:57 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL for-2.9 7/7] cirrus: stop passing around src pointers in the blitter X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 --- 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 9ae1d4b..afc290a 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -178,7 +178,7 @@ =20 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, @@ -322,7 +322,7 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, bo= ol dst_only) } =20 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) { @@ -334,6 +334,45 @@ static void cirrus_bitblt_fill_nop(CirrusVGAState *s, { } =20 +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 =3D (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1= ) & ~1]; + } else { + /* videotovideo */ + src =3D (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 =3D (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1= ) & ~3]; + } else { + /* videotovideo */ + src =3D (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" @@ -676,10 +715,10 @@ static void cirrus_invalidate_region(CirrusVGAState *= s, int off_begin, } } =20 -static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videos= rc) +static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s) { uint32_t patternsize; - uint8_t *src; + bool videosrc =3D !s->cirrus_srccounter; =20 if (videosrc) { switch (s->vga.get_bpp(&s->vga)) { @@ -700,16 +739,14 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGA= State *s, bool videosrc) if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) { return 0; } - src =3D s->vga.vram_ptr + s->cirrus_blt_srcaddr; - } else { - src =3D s->cirrus_bltbuf; } =20 if (blit_is_unsafe(s, true)) { return 0; } =20 - (*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, @@ -746,7 +783,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, i= nt blt_rop) =20 static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) { - return cirrus_bitblt_common_patterncopy(s, true); + return cirrus_bitblt_common_patterncopy(s); } =20 static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int = h) @@ -796,7 +833,7 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, i= nt src, int w, int h) } =20 (*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); =20 @@ -839,7 +876,7 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAStat= e * s) =20 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 =3D 0; cirrus_bitblt_reset(s); @@ -847,7 +884,7 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAStat= e * s) /* at least one scan line */ do { (*s->cirrus_rop)(s, s->cirrus_blt_dstaddr, - s->cirrus_bltbuf, 0, 0, s->cirrus_blt_wi= dth, 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 +=3D s->cirrus_blt_dstpitch; diff --git a/hw/display/cirrus_vga_rop.h b/hw/display/cirrus_vga_rop.h index 1aa778d..c61a677 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, =20 for (y =3D 0; y < bltheight; y++) { for (x =3D 0; x < bltwidth; x++) { - ROP_OP(s, dstaddr, *src); + ROP_OP(s, dstaddr, cirrus_src(s, srcaddr)); dstaddr++; - src++; + srcaddr++; } dstaddr +=3D dstpitch; - src +=3D srcpitch; + srcaddr +=3D srcpitch; } } =20 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)(CirrusVGAStat= e *s, srcpitch +=3D bltwidth; for (y =3D 0; y < bltheight; y++) { for (x =3D 0; x < bltwidth; x++) { - ROP_OP(s, dstaddr, *src); + ROP_OP(s, dstaddr, cirrus_src(s, srcaddr)); dstaddr--; - src--; + srcaddr--; } dstaddr +=3D dstpitch; - src +=3D srcpitch; + srcaddr +=3D srcpitch; } } =20 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, =20 for (y =3D 0; y < bltheight; y++) { for (x =3D 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 +=3D dstpitch; - src +=3D srcpitch; + srcaddr +=3D srcpitch; } } =20 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 +=3D bltwidth; for (y =3D 0; y < bltheight; y++) { for (x =3D 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 +=3D dstpitch; - src +=3D srcpitch; + srcaddr +=3D srcpitch; } } =20 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),_1= 6)(CirrusVGAState *s, =20 for (y =3D 0; y < bltheight; y++) { for (x =3D 0; x < bltwidth; x+=3D2) { - ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp); + ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp); dstaddr +=3D 2; - src +=3D 2; + srcaddr +=3D 2; } dstaddr +=3D dstpitch; - src +=3D srcpitch; + srcaddr +=3D srcpitch; } } =20 static void glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, uint32_t dstaddr, - const uint8_t *sr= c, + 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 +=3D bltwidth; for (y =3D 0; y < bltheight; y++) { for (x =3D 0; x < bltwidth; x+=3D2) { - ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp); + ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp); dstaddr -=3D 2; - src -=3D 2; + srcaddr -=3D 2; } dstaddr +=3D dstpitch; - src +=3D srcpitch; + srcaddr +=3D srcpitch; } } =20 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 =3D=3D 24 int skipleft =3D s->vga.gr[0x2f] & 0x1f; #else @@ -66,22 +66,24 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) for(y =3D 0; y < bltheight; y++) { pattern_x =3D skipleft; addr =3D dstaddr + skipleft; - src1 =3D src + pattern_y * pattern_pitch; + src1addr =3D srcaddr + pattern_y * pattern_pitch; for (x =3D skipleft; x < bltwidth; x +=3D (DEPTH / 8)) { #if DEPTH =3D=3D 8 - col =3D src1[pattern_x]; + col =3D cirrus_src(s, src1addr + pattern_x); pattern_x =3D (pattern_x + 1) & 7; #elif DEPTH =3D=3D 16 - col =3D ((uint16_t *)(src1 + pattern_x))[0]; + col =3D cirrus_src16(s, src1addr + pattern_x); pattern_x =3D (pattern_x + 2) & 15; #elif DEPTH =3D=3D 24 { - const uint8_t *src2 =3D src1 + pattern_x * 3; - col =3D src2[0] | (src2[1] << 8) | (src2[2] << 16); + uint32_t src2addr =3D src1addr + pattern_x * 3; + col =3D cirrus_src(s, src2addr) | + (cirrus_src(s, src2addr + 1) << 8) | + (cirrus_src(s, src2addr + 2) << 16); pattern_x =3D (pattern_x + 1) & 7; } #else - col =3D ((uint32_t *)(src1 + pattern_x))[0]; + col =3D cirrus_src32(s, src1addr + pattern_x); pattern_x =3D (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) =20 for(y =3D 0; y < bltheight; y++) { bitmask =3D 0x80 >> srcskipleft; - bits =3D *src++ ^ bits_xor; + bits =3D cirrus_src(s, srcaddr++) ^ bits_xor; addr =3D dstaddr + dstskipleft; for (x =3D dstskipleft; x < bltwidth; x +=3D (DEPTH / 8)) { if ((bitmask & 0xff) =3D=3D 0) { bitmask =3D 0x80; - bits =3D *src++ ^ bits_xor; + bits =3D cirrus_src(s, srcaddr++) ^ bits_xor; } index =3D (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), _),DEP= TH) colors[1] =3D s->cirrus_blt_fgcol; for(y =3D 0; y < bltheight; y++) { bitmask =3D 0x80 >> srcskipleft; - bits =3D *src++; + bits =3D cirrus_src(s, srcaddr++); addr =3D dstaddr + dstskipleft; for (x =3D dstskipleft; x < bltwidth; x +=3D (DEPTH / 8)) { if ((bitmask & 0xff) =3D=3D 0) { bitmask =3D 0x80; - bits =3D *src++; + bits =3D cirrus_src(s, srcaddr++); } col =3D 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 =3D s->cirrus_blt_srcaddr & 7; =20 for(y =3D 0; y < bltheight; y++) { - bits =3D src[pattern_y] ^ bits_xor; + bits =3D cirrus_src(s, srcaddr + pattern_y) ^ bits_xor; bitpos =3D 7 - srcskipleft; addr =3D dstaddr + dstskipleft; for (x =3D dstskipleft; x < bltwidth; x +=3D (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 =3D s->cirrus_blt_srcaddr & 7; =20 for(y =3D 0; y < bltheight; y++) { - bits =3D src[pattern_y]; + bits =3D cirrus_src(s, srcaddr + pattern_y); bitpos =3D 7 - srcskipleft; addr =3D dstaddr + dstskipleft; for (x =3D dstskipleft; x < bltwidth; x +=3D (DEPTH / 8)) { --=20 1.8.3.1