From patchwork Tue Aug 16 13:51:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 9283987 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 211CD6086A for ; Tue, 16 Aug 2016 13:54:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 08C8C28C7B for ; Tue, 16 Aug 2016 13:54:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F150228C85; Tue, 16 Aug 2016 13:54:13 +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 3642428C7B for ; Tue, 16 Aug 2016 13:54:12 +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 1bZemA-0001iV-FG; Tue, 16 Aug 2016 13:51:30 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bZem9-0001iP-0e for xen-devel@lists.xenproject.org; Tue, 16 Aug 2016 13:51:29 +0000 Received: from [193.109.254.147] by server-6.bemta-6.messagelabs.com id 74/BC-11175-06A13B75; Tue, 16 Aug 2016 13:51:28 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrHIsWRWlGSWpSXmKPExsXS6fjDSzdOanO 4wc95phbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8bMtUfZCpZ6V0x5F9TAeNG0i5GTQ0ggT+LY m35GEJtXwE7i/7R2VhBbQsBQ4un762wgNouAqsSlZdfBatgE1CXanm0HquHgEBEwkDh3NAnEZ BbQl9i2jgWkQhjInLuhjQUkzCsgKPF3hzBImBlo+IEVDYwTGLlmIWRmIclA2FoSD3/dYoGwtS WWLXzNPAtsvrTE8n8cEKaNxKqHIagqQGx3iW3HrzIvYORYxahRnFpUllqka2iml1SUmZ5Rkpu YmaNraGCml5taXJyYnpqTmFSsl5yfu4kRGHYMQLCD8f7GgEOMkhxMSqK8MyduDBfiS8pPqcxI LM6ILyrNSS0+xKjBwSGwbdfqC4xSLHn5ealKEryukpvDhQSLUtNTK9Iyc4CRAVMqwcGjJMIbB JLmLS5IzC3OTIdInWJUlBLnvSoBlBAASWSU5sG1waLxEqOslDAvI9BRQjwFqUW5mSWo8q8YxT kYlYR5k0DG82TmlcBNfwW0mAlosb70BpDFJYkIKakGRrVTHxXNJ5XUr3pUa9zjbuv9dg533e3 GzEmfbr7WCdjUFTHB8lc5F+OGl5xWuQvCQuVcLmRPm/epW/7l8oW7LT36Sxvknmy6cKk24Ez1 7eCsWvtfN/Z/VQl8bF7/5Sbvx87gI1PZ2C02/Am6FTsz3Lwj3t5xruvz/G/Pbn+Oml3cWdL3V 9L1pRJLcUaioRZzUXEiAK/DUtzBAgAA X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-6.tower-27.messagelabs.com!1471355484!54319175!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 49875 invoked from network); 16 Aug 2016 13:51:26 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-6.tower-27.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 16 Aug 2016 13:51:26 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Tue, 16 Aug 2016 07:51:24 -0600 Message-Id: <57B3367B0200007800106590@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.1 Date: Tue, 16 Aug 2016 07:51:23 -0600 From: "Jan Beulich" To: "xen-devel" Mime-Version: 1.0 Cc: Andrew Cooper Subject: [Xen-devel] [PATCH] x86emul: improve LOCK handling 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 Certain opcodes would so far not have got #UD when a LOCK prefix was present. Adjust this by - moving the too early generic check into destination operand decoding, where DstNone and DstReg already have respective handling - switching source and destination of TEST r,r/m, for it to be taken care of by aforementioned generic checks - explicitly dealing with all forms of CMP, SHLD, SHRD, as well as TEST $imm,r/m To make the handling of opcodes F6 and F7 more obvious, reduce the amount of state set in the table, and adjust the respective switch() statement accordingly. Also eliminate the latent bug of the check in DstNone handling not considering the opcode extension set. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- This will only apply cleanly on top of https://lists.xenproject.org/archives/html/xen-devel/2016-08/msg01975.html. x86emul: improve LOCK handling Certain opcodes would so far not have got #UD when a LOCK prefix was present. Adjust this by - moving the too early generic check into destination operand decoding, where DstNone and DstReg already have respective handling - switching source and destination of TEST r,r/m, for it to be taken care of by aforementioned generic checks - explicitly dealing with all forms of CMP, SHLD, SHRD, as well as TEST $imm,r/m To make the handling of opcodes F6 and F7 more obvious, reduce the amount of state set in the table, and adjust the respective switch() statement accordingly. Also eliminate the latent bug of the check in DstNone handling not considering the opcode extension set. Signed-off-by: Jan Beulich --- This will only apply cleanly on top of https://lists.xenproject.org/archives/html/xen-devel/2016-08/msg01975.html. --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -110,7 +110,7 @@ static uint8_t opcode_table[256] = { /* 0x80 - 0x87 */ ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM, ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, - ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, + ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, /* 0x88 - 0x8F */ ByteOp|DstMem|SrcReg|ModRM|Mov, DstMem|SrcReg|ModRM|Mov, @@ -169,8 +169,7 @@ static uint8_t opcode_table[256] = { DstEax|SrcImplicit, DstEax|SrcImplicit, ImplicitOps, ImplicitOps, /* 0xF0 - 0xF7 */ 0, ImplicitOps, 0, 0, - ImplicitOps, ImplicitOps, - ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM, + ImplicitOps, ImplicitOps, ByteOp|ModRM, ModRM, /* 0xF8 - 0xFF */ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM @@ -1651,9 +1650,6 @@ x86_emulate( } } - /* Lock prefix is allowed only on RMW instructions. */ - generate_exception_if((d & Mov) && lock_prefix, EXC_UD, -1); - /* ModRM and SIB bytes. */ if ( d & ModRM ) { @@ -1729,13 +1725,17 @@ x86_emulate( switch ( modrm_reg & 7 ) { case 0 ... 1: /* test */ - d = (d & ~SrcMask) | SrcImm; + d |= DstMem | SrcImm; + break; + case 2: /* not */ + case 3: /* neg */ + d |= DstMem; break; case 4: /* mul */ case 5: /* imul */ case 6: /* div */ case 7: /* idiv */ - d = (d & (ByteOp | ModRM)) | DstEax | SrcMem; + d |= DstEax | SrcMem; break; } break; @@ -1983,8 +1983,9 @@ x86_emulate( */ generate_exception_if( lock_prefix && - ((b < 0x20) || (b > 0x23)) && /* MOV CRn/DRn */ - (b != 0xc7), /* CMPXCHG{8,16}B */ + (ext != ext_0f || + (((b < 0x20) || (b > 0x23)) && /* MOV CRn/DRn */ + (b != 0xc7))), /* CMPXCHG{8,16}B */ EXC_UD, -1); dst.type = OP_NONE; break; @@ -2062,6 +2063,8 @@ x86_emulate( goto done; dst.orig_val = dst.val; } + else /* Lock prefix is allowed only on RMW instructions. */ + generate_exception_if(lock_prefix, EXC_UD, -1); break; } @@ -2111,6 +2114,7 @@ x86_emulate( break; case 0x38 ... 0x3d: cmp: /* cmp */ + generate_exception_if(lock_prefix, EXC_UD, -1); emulate_2op_SrcV("cmp", src, dst, _regs.eflags); dst.type = OP_NONE; break; @@ -3545,6 +3549,7 @@ x86_emulate( unsigned long u[2], v; case 0 ... 1: /* test */ + generate_exception_if(lock_prefix, EXC_UD, -1); goto test; case 2: /* not */ dst.val = ~dst.val; @@ -4507,6 +4512,7 @@ x86_emulate( case 0xad: /* shrd %%cl,r,r/m */ { uint8_t shift, width = dst.bytes << 3; + generate_exception_if(lock_prefix, EXC_UD, -1); if ( b & 1 ) shift = _regs.ecx; else --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -110,7 +110,7 @@ static uint8_t opcode_table[256] = { /* 0x80 - 0x87 */ ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM, ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, - ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, + ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, /* 0x88 - 0x8F */ ByteOp|DstMem|SrcReg|ModRM|Mov, DstMem|SrcReg|ModRM|Mov, @@ -169,8 +169,7 @@ static uint8_t opcode_table[256] = { DstEax|SrcImplicit, DstEax|SrcImplicit, ImplicitOps, ImplicitOps, /* 0xF0 - 0xF7 */ 0, ImplicitOps, 0, 0, - ImplicitOps, ImplicitOps, - ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM, + ImplicitOps, ImplicitOps, ByteOp|ModRM, ModRM, /* 0xF8 - 0xFF */ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM @@ -1651,9 +1650,6 @@ x86_emulate( } } - /* Lock prefix is allowed only on RMW instructions. */ - generate_exception_if((d & Mov) && lock_prefix, EXC_UD, -1); - /* ModRM and SIB bytes. */ if ( d & ModRM ) { @@ -1729,13 +1725,17 @@ x86_emulate( switch ( modrm_reg & 7 ) { case 0 ... 1: /* test */ - d = (d & ~SrcMask) | SrcImm; + d |= DstMem | SrcImm; + break; + case 2: /* not */ + case 3: /* neg */ + d |= DstMem; break; case 4: /* mul */ case 5: /* imul */ case 6: /* div */ case 7: /* idiv */ - d = (d & (ByteOp | ModRM)) | DstEax | SrcMem; + d |= DstEax | SrcMem; break; } break; @@ -1983,8 +1983,9 @@ x86_emulate( */ generate_exception_if( lock_prefix && - ((b < 0x20) || (b > 0x23)) && /* MOV CRn/DRn */ - (b != 0xc7), /* CMPXCHG{8,16}B */ + (ext != ext_0f || + (((b < 0x20) || (b > 0x23)) && /* MOV CRn/DRn */ + (b != 0xc7))), /* CMPXCHG{8,16}B */ EXC_UD, -1); dst.type = OP_NONE; break; @@ -2062,6 +2063,8 @@ x86_emulate( goto done; dst.orig_val = dst.val; } + else /* Lock prefix is allowed only on RMW instructions. */ + generate_exception_if(lock_prefix, EXC_UD, -1); break; } @@ -2111,6 +2114,7 @@ x86_emulate( break; case 0x38 ... 0x3d: cmp: /* cmp */ + generate_exception_if(lock_prefix, EXC_UD, -1); emulate_2op_SrcV("cmp", src, dst, _regs.eflags); dst.type = OP_NONE; break; @@ -3545,6 +3549,7 @@ x86_emulate( unsigned long u[2], v; case 0 ... 1: /* test */ + generate_exception_if(lock_prefix, EXC_UD, -1); goto test; case 2: /* not */ dst.val = ~dst.val; @@ -4507,6 +4512,7 @@ x86_emulate( case 0xad: /* shrd %%cl,r,r/m */ { uint8_t shift, width = dst.bytes << 3; + generate_exception_if(lock_prefix, EXC_UD, -1); if ( b & 1 ) shift = _regs.ecx; else