From patchwork Thu Sep 29 13:08:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 9356423 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C3F06600C8 for ; Thu, 29 Sep 2016 13:10:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B1EE929A08 for ; Thu, 29 Sep 2016 13:10:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A1B6129A0C; Thu, 29 Sep 2016 13:10:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9CFDD29A08 for ; Thu, 29 Sep 2016 13:10:53 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bpb4R-0000DZ-Fv; Thu, 29 Sep 2016 13:08:15 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bpb4Q-0000DT-Q6 for xen-devel@lists.xenproject.org; Thu, 29 Sep 2016 13:08:14 +0000 Received: from [85.158.139.211] by server-9.bemta-5.messagelabs.com id F4/31-13924-D321DE75; Thu, 29 Sep 2016 13:08:13 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrMIsWRWlGSWpSXmKPExsXS6fjDS9dG6G2 4wd89Chbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8aMbV1sBcu9KlbMvsbSwNij38XIySEkkCfx bHoncxcjBwevgJ1E2+l6kLCEgKHE0/fX2UBsFgFVic/N55lAbDYBdYm2Z9tZQcpFBAwkzh1NA gkzCyRJtH9tYwexhYFau94tgpooKPF3hzBEiZ3E+cMNrBMYuWYhZGYhyUDYWhIPf91igbC1JZ YtfM0MUs4sIC2x/B8HRNhK4vS1O0yoSkBsV4l1j+8yLmDkWMWoXpxaVJZapGusl1SUmZ5Rkpu YmaNraGCql5taXJyYnpqTmFSsl5yfu4kRGHgMQLCDce8/p0OMkhxMSqK8V+e9CRfiS8pPqcxI LM6ILyrNSS0+xCjDwaEkwTtP8G24kGBRanpqRVpmDjAGYNISHDxKIryzQNK8xQWJucWZ6RCpU 4yKUuK8e0ASAiCJjNI8uDZY3F1ilJUS5mUEOkSIpyC1KDezBFX+FaM4B6OSMK8eyBSezLwSuO mvgBYzAS3OP/oGZHFJIkJKqoExI+teju3NjQqLmJhWTXhhMcsrdXu+7TbN+d9DF/jvE1kkvnu S3/ScrqMPlfzfGrHk+tm6de740S28zCfJvZiX48rezS2lqvbcanatbx5UHmI6y6UXpfG2v7j3 wZn8F3LnlBUeHQkuuuWjtndWcsAMxV9uz+4yzp6Q7Jrj3WTlKyC5/un6mxpKLMUZiYZazEXFi QCNk266tgIAAA== X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-8.tower-206.messagelabs.com!1475154490!62088129!1 X-Originating-IP: [137.65.248.74] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 8.84; banners=-,-,- X-VirusChecked: Checked Received: (qmail 40599 invoked from network); 29 Sep 2016 13:08:12 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-8.tower-206.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 29 Sep 2016 13:08:12 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Thu, 29 Sep 2016 07:08:09 -0600 Message-Id: <57ED2E5A0200007800113BDC@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.1 Date: Thu, 29 Sep 2016 07:08:10 -0600 From: "Jan Beulich" To: "xen-devel" Mime-Version: 1.0 Cc: Andrew Cooper Subject: [Xen-devel] [PATCH] x86emul: fix {,i}mul and {,i}div X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Commit a3db233ede ("x86emul: use DstEax also for {,I}{MUL,DIV}") went a little too far: DstEax and SrcEax weren't really meant to be used together with ModRM - they assume modrm_reg remains zero by the time the destination / source register pointer gets calculated. Don't fully undo that commit though, but instead just correct the register pointer, and don't use dst.val as input for mul and imul (div and idiv did avoid that already). Reported-by: Konrad Rzeszutek Wilk Signed-off-by: Jan Beulich x86emul: fix {,i}mul and {,i}div Commit a3db233ede ("x86emul: use DstEax also for {,I}{MUL,DIV}") went a little too far: DstEax and SrcEax weren't really meant to be used together with ModRM - they assume modrm_reg remains zero by the time the destination / source register pointer gets calculated. Don't fully undo that commit though, but instead just correct the register pointer, and don't use dst.val as input for mul and imul (div and idiv did avoid that already). Reported-by: Konrad Rzeszutek Wilk Signed-off-by: Jan Beulich --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -3845,18 +3845,19 @@ x86_emulate( emulate_1op("neg", dst, _regs.eflags); break; case 4: /* mul */ + dst.reg = (unsigned long *)&_regs.eax; _regs.eflags &= ~(EFLG_OF|EFLG_CF); switch ( dst.bytes ) { case 1: - dst.val = (uint8_t)dst.val; + dst.val = (uint8_t)_regs.eax; dst.val *= src.val; if ( (uint8_t)dst.val != (uint16_t)dst.val ) _regs.eflags |= EFLG_OF|EFLG_CF; dst.bytes = 2; break; case 2: - dst.val = (uint16_t)dst.val; + dst.val = (uint16_t)_regs.eax; dst.val *= src.val; if ( (uint16_t)dst.val != (uint32_t)dst.val ) _regs.eflags |= EFLG_OF|EFLG_CF; @@ -3864,7 +3865,7 @@ x86_emulate( break; #ifdef __x86_64__ case 4: - dst.val = (uint32_t)dst.val; + dst.val = _regs._eax; dst.val *= src.val; if ( (uint32_t)dst.val != dst.val ) _regs.eflags |= EFLG_OF|EFLG_CF; @@ -3873,7 +3874,7 @@ x86_emulate( #endif default: u[0] = src.val; - u[1] = dst.val; + u[1] = _regs.eax; if ( mul_dbl(u) ) _regs.eflags |= EFLG_OF|EFLG_CF; _regs.edx = u[1]; @@ -3882,12 +3883,13 @@ x86_emulate( } break; case 5: /* imul */ + dst.reg = (unsigned long *)&_regs.eax; imul: _regs.eflags &= ~(EFLG_OF|EFLG_CF); switch ( dst.bytes ) { case 1: - dst.val = (int8_t)src.val * (int8_t)dst.val; + dst.val = (int8_t)src.val * (int8_t)_regs.eax; if ( (int8_t)dst.val != (int16_t)dst.val ) _regs.eflags |= EFLG_OF|EFLG_CF; ASSERT(b > 0x6b); @@ -3895,7 +3897,7 @@ x86_emulate( break; case 2: dst.val = ((uint32_t)(int16_t)src.val * - (uint32_t)(int16_t)dst.val); + (uint32_t)(int16_t)_regs.eax); if ( (int16_t)dst.val != (int32_t)dst.val ) _regs.eflags |= EFLG_OF|EFLG_CF; if ( b > 0x6b ) @@ -3904,7 +3906,7 @@ x86_emulate( #ifdef __x86_64__ case 4: dst.val = ((uint64_t)(int32_t)src.val * - (uint64_t)(int32_t)dst.val); + (uint64_t)(int32_t)_regs.eax); if ( (int32_t)dst.val != dst.val ) _regs.eflags |= EFLG_OF|EFLG_CF; if ( b > 0x6b ) @@ -3913,7 +3915,7 @@ x86_emulate( #endif default: u[0] = src.val; - u[1] = dst.val; + u[1] = _regs.eax; if ( imul_dbl(u) ) _regs.eflags |= EFLG_OF|EFLG_CF; if ( b > 0x6b ) @@ -3923,6 +3925,7 @@ x86_emulate( } break; case 6: /* div */ + dst.reg = (unsigned long *)&_regs.eax; switch ( src.bytes ) { case 1: @@ -3968,6 +3971,7 @@ x86_emulate( } break; case 7: /* idiv */ + dst.reg = (unsigned long *)&_regs.eax; switch ( src.bytes ) { case 1: Reviewed-by: Andrew Cooper Tested-by: Konrad Rzeszutek Wilk --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -3845,18 +3845,19 @@ x86_emulate( emulate_1op("neg", dst, _regs.eflags); break; case 4: /* mul */ + dst.reg = (unsigned long *)&_regs.eax; _regs.eflags &= ~(EFLG_OF|EFLG_CF); switch ( dst.bytes ) { case 1: - dst.val = (uint8_t)dst.val; + dst.val = (uint8_t)_regs.eax; dst.val *= src.val; if ( (uint8_t)dst.val != (uint16_t)dst.val ) _regs.eflags |= EFLG_OF|EFLG_CF; dst.bytes = 2; break; case 2: - dst.val = (uint16_t)dst.val; + dst.val = (uint16_t)_regs.eax; dst.val *= src.val; if ( (uint16_t)dst.val != (uint32_t)dst.val ) _regs.eflags |= EFLG_OF|EFLG_CF; @@ -3864,7 +3865,7 @@ x86_emulate( break; #ifdef __x86_64__ case 4: - dst.val = (uint32_t)dst.val; + dst.val = _regs._eax; dst.val *= src.val; if ( (uint32_t)dst.val != dst.val ) _regs.eflags |= EFLG_OF|EFLG_CF; @@ -3873,7 +3874,7 @@ x86_emulate( #endif default: u[0] = src.val; - u[1] = dst.val; + u[1] = _regs.eax; if ( mul_dbl(u) ) _regs.eflags |= EFLG_OF|EFLG_CF; _regs.edx = u[1]; @@ -3882,12 +3883,13 @@ x86_emulate( } break; case 5: /* imul */ + dst.reg = (unsigned long *)&_regs.eax; imul: _regs.eflags &= ~(EFLG_OF|EFLG_CF); switch ( dst.bytes ) { case 1: - dst.val = (int8_t)src.val * (int8_t)dst.val; + dst.val = (int8_t)src.val * (int8_t)_regs.eax; if ( (int8_t)dst.val != (int16_t)dst.val ) _regs.eflags |= EFLG_OF|EFLG_CF; ASSERT(b > 0x6b); @@ -3895,7 +3897,7 @@ x86_emulate( break; case 2: dst.val = ((uint32_t)(int16_t)src.val * - (uint32_t)(int16_t)dst.val); + (uint32_t)(int16_t)_regs.eax); if ( (int16_t)dst.val != (int32_t)dst.val ) _regs.eflags |= EFLG_OF|EFLG_CF; if ( b > 0x6b ) @@ -3904,7 +3906,7 @@ x86_emulate( #ifdef __x86_64__ case 4: dst.val = ((uint64_t)(int32_t)src.val * - (uint64_t)(int32_t)dst.val); + (uint64_t)(int32_t)_regs.eax); if ( (int32_t)dst.val != dst.val ) _regs.eflags |= EFLG_OF|EFLG_CF; if ( b > 0x6b ) @@ -3913,7 +3915,7 @@ x86_emulate( #endif default: u[0] = src.val; - u[1] = dst.val; + u[1] = _regs.eax; if ( imul_dbl(u) ) _regs.eflags |= EFLG_OF|EFLG_CF; if ( b > 0x6b ) @@ -3923,6 +3925,7 @@ x86_emulate( } break; case 6: /* div */ + dst.reg = (unsigned long *)&_regs.eax; switch ( src.bytes ) { case 1: @@ -3968,6 +3971,7 @@ x86_emulate( } break; case 7: /* idiv */ + dst.reg = (unsigned long *)&_regs.eax; switch ( src.bytes ) { case 1: