From patchwork Thu Aug 9 11:46:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liran Alon X-Patchwork-Id: 955481 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=oracle.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=oracle.com header.i=@oracle.com header.b="u0a3v68K"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41mRf32Y4Xz9s1c for ; Thu, 9 Aug 2018 22:00:27 +1000 (AEST) Received: from localhost ([::1]:50081 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fnjc8-0008Fp-Vj for incoming@patchwork.ozlabs.org; Thu, 09 Aug 2018 08:00:25 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56623) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fnjQR-0005ba-Lv for qemu-devel@nongnu.org; Thu, 09 Aug 2018 07:48:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fnjQP-0007fT-1s for qemu-devel@nongnu.org; Thu, 09 Aug 2018 07:48:19 -0400 Received: from aserp2120.oracle.com ([141.146.126.78]:37398) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fnjQO-0007fC-NJ for qemu-devel@nongnu.org; Thu, 09 Aug 2018 07:48:16 -0400 Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w79BiCmK177696; Thu, 9 Aug 2018 11:48:15 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=RyZnJu2Pi/urius5ZemuucRlNHtpZqC48VVS/Nt1PtM=; b=u0a3v68KEfURXRN3n9DTBztVvQqTGjUCCCd9OTymw0haxTr/UzpBw+BCDpk8fDCrGDgU avsEZJ6Pxu/cjwBdJcagZiCWUuJuj4UP7m7sncYWWLj5FOdB1Cp2we24uRR58GJCtgRH IErojfw07C91/uiprw3j4huBMYs2VMEcHrwlCWdswJfBu/ihLDJYMwt7vQEjNFku2EAF oGkPkuNcyfCjtbpCAkrw/pVPdsDvrx+Y+0tCbejirM9HuvqEQ7v4+mmICr6CD0VsxF+r fPIBL7rJ2hCnImdFbCffbTUCXpI71Hy2PridF6fWraWMYidUEfzDpsMpiLXegIliNOOO 9Q== Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp2120.oracle.com with ESMTP id 2kn43p2uyp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 09 Aug 2018 11:48:15 +0000 Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id w79BmFpM022696 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 9 Aug 2018 11:48:15 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id w79BmFZL031503; Thu, 9 Aug 2018 11:48:15 GMT Received: from liran-pc.ravello.local (/213.57.127.2) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 09 Aug 2018 04:48:14 -0700 From: Liran Alon To: qemu-devel@nongnu.org Date: Thu, 9 Aug 2018 14:46:40 +0300 Message-Id: <1533815202-11967-28-git-send-email-liran.alon@oracle.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1533815202-11967-1-git-send-email-liran.alon@oracle.com> References: <1533815202-11967-1-git-send-email-liran.alon@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8979 signatures=668707 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1807170000 definitions=main-1808090123 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 141.146.126.78 Subject: [Qemu-devel] [PATCH 27/29] vmsvga: Add support for pitchlock register (a display line stride) 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: habkost@redhat.com, mtosatti@redhat.com, Liran Alon , kraxel@redhat.com, pbonzini@redhat.com, rth@twiddle.net, Leonid Shatz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Leonid Shatz Indicate support of SVGA_REG_PITCHLOCK in device capabilities. Value written by driver to SVGA_REG_PITCHLOCK is used to overwrite the default line length derived from display width and bpp. Due to lack of clear documentation, we resume using default formula for line length when screen width is updated more than once without update to SVGA_REG_PITCHLOCK register, which works for all tested guests using vmsvga. SVGA_REG_PITCHLOCK is required by Linux kernel vmsvga driver (See Linux kernel vmw_driver_load()). Signed-off-by: Leonid Shatz Reviewed-by: Darren Kenny Signed-off-by: Liran Alon --- hw/display/vmware_vga.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index edd336e65005..bd7202833081 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -82,6 +82,8 @@ struct vmsvga_state_s { uint32_t irq_mask; uint32_t irq_status; uint32_t display_id; + uint32_t pitchlock; + int use_pitchlock; }; #define TYPE_VMWARE_SVGA "vmware-svga" @@ -1198,9 +1200,10 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) break; case SVGA_REG_BYTES_PER_LINE: - if (s->new_width) { - ret = (s->new_depth * s->new_width) / 8; - } else { + ret = (s->use_pitchlock >= 0) ? + s->pitchlock : + ((s->new_depth * s->new_width) / 8); + if (!ret) { ret = surface_stride(surface); } break; @@ -1242,6 +1245,7 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) caps |= SVGA_CAP_EXTENDED_FIFO; caps |= SVGA_CAP_IRQMASK; caps |= SVGA_CAP_DISPLAY_TOPOLOGY; + caps |= SVGA_CAP_PITCHLOCK; ret = caps; break; @@ -1294,11 +1298,14 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) break; case SVGA_REG_NUM_DISPLAYS: - case SVGA_REG_PITCHLOCK: case SVGA_PALETTE_BASE ... SVGA_PALETTE_END: ret = 0; break; + case SVGA_REG_PITCHLOCK: + ret = s->pitchlock; + break; + case SVGA_REG_IRQMASK: ret = s->irq_mask; break; @@ -1394,6 +1401,13 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) if (value <= SVGA_MAX_WIDTH) { s->new_width = value; s->invalidated = 1; + /* This is a hack used to drop effective pitchlock setting + * when guest writes screen width without prior write to + * the pitchlock register. + */ + if (s->use_pitchlock >= 0) { + s->use_pitchlock--; + } } else { printf("%s: Bad width: %i\n", __func__, value); } @@ -1464,10 +1478,15 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) case SVGA_REG_DEPTH: case SVGA_REG_MEM_REGS: case SVGA_REG_NUM_DISPLAYS: - case SVGA_REG_PITCHLOCK: case SVGA_PALETTE_BASE ... SVGA_PALETTE_END: break; + case SVGA_REG_PITCHLOCK: + s->pitchlock = value; + s->use_pitchlock = (value > 0) ? 1 : -1; + s->invalidated = 1; + break; + case SVGA_REG_IRQMASK: s->irq_mask = value; break; @@ -1540,16 +1559,20 @@ static void vmsvga_bios_write(void *opaque, uint32_t address, uint32_t data) static inline void vmsvga_check_size(struct vmsvga_state_s *s) { DisplaySurface *surface = qemu_console_surface(s->vga.con); + uint32_t new_stride; + new_stride = (s->use_pitchlock >= 0) ? + s->pitchlock : + ((s->new_depth * s->new_width) / 8); if (s->new_width != surface_width(surface) || s->new_height != surface_height(surface) || + (new_stride != surface_stride(surface)) || s->new_depth != surface_bits_per_pixel(surface)) { - int stride = (s->new_depth * s->new_width) / 8; pixman_format_code_t format = qemu_default_pixman_format(s->new_depth, true); trace_vmware_setmode(s->new_width, s->new_height, s->new_depth); surface = qemu_create_displaysurface_from(s->new_width, s->new_height, - format, stride, + format, new_stride, s->vga.vram_ptr); dpy_gfx_replace_surface(s->vga.con, surface); s->invalidated = 1; @@ -1598,6 +1621,8 @@ static void vmsvga_reset(DeviceState *dev) s->irq_status = 0; s->last_fifo_cursor_count = 0; s->display_id = SVGA_ID_INVALID; + s->pitchlock = 0; + s->use_pitchlock = -1; vga_dirty_log_start(&s->vga); } @@ -1633,6 +1658,8 @@ static int vmsvga_post_load(void *opaque, int version_id) s->irq_status = 0; s->last_fifo_cursor_count = 0; s->display_id = SVGA_ID_INVALID; + s->pitchlock = 0; + s->use_pitchlock = -1; } return 0; @@ -1664,6 +1691,8 @@ static const VMStateDescription vmstate_vmware_vga_internal = { VMSTATE_UINT32_V(irq_status, struct vmsvga_state_s, 1), VMSTATE_UINT32_V(last_fifo_cursor_count, struct vmsvga_state_s, 1), VMSTATE_UINT32_V(display_id, struct vmsvga_state_s, 1), + VMSTATE_UINT32_V(pitchlock, struct vmsvga_state_s, 1), + VMSTATE_INT32_V(use_pitchlock, struct vmsvga_state_s, 1), VMSTATE_END_OF_LIST() } };