From patchwork Thu Sep 8 13:11:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 9321363 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 82EED6077F for ; Thu, 8 Sep 2016 13:13:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 74A9129870 for ; Thu, 8 Sep 2016 13:13:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 696A929876; Thu, 8 Sep 2016 13:13:37 +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 E685829870 for ; Thu, 8 Sep 2016 13:13:33 +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 1bhz74-0000Vs-6J; Thu, 08 Sep 2016 13:11:30 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bhz72-0000Ve-KV for xen-devel@lists.xenproject.org; Thu, 08 Sep 2016 13:11:28 +0000 Received: from [85.158.137.68] by server-16.bemta-3.messagelabs.com id 38/1B-29579-F7361D75; Thu, 08 Sep 2016 13:11:27 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrNIsWRWlGSWpSXmKPExsXS6fjDS7c++WK 4wedz3Bbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8a2ruusBZudKp72LWJuYJyr0cXIySEkkCfx 49cpdhCbV8BOYt3OaawgtoSAocTT99fZuhg5OFgEVCUOv8wACbMJqEu0PdvOChIWETCQOHc0C cRkFtCX2LaOBaRCGCh6+uY6NojhdhLPTh0Ei3MK2Et8aZ3DCFLOKyAo8XeHMEiYGajk5PWjrB MYeWYhZGYhyUDYWhIPf91igbC1JZYtfM08C2yvtMTyfxwQYUuJd+8vMqEqAbFdJDZv38u6gJF jFaNGcWpRWWqRrqGRXlJRZnpGSW5iZo6uoYGxXm5qcXFiempOYlKxXnJ+7iZGYKAyAMEOxlfd zocYJTmYlER5fYovhAvxJeWnVGYkFmfEF5XmpBYfYpTh4FCS4A1PuhguJFiUmp5akZaZA4wZm LQEB4+SCC8bSJq3uCAxtzgzHSJ1ilFRSpzXGCQhAJLIKM2Da4PF6SVGWSlhXkagQ4R4ClKLcj NLUOVfMYpzMCoJ835NBJrCk5lXAjf9FdBiJqDFQqfOgywuSURISTUwFod33POOfvnw7ULJ+O3 bXqnkvHJuLci7u157kfGOHW9lQwL2ss1fuGwrb+EBrWl+vwJyV9jd8uYKrxC95xfqZvn+7reN 0z+dPHHu7sepBYdFLm7RWtBmdEJaeu3zeXMWNHtl7dy2M+DeBPaNe/pMK94Kvjg9T/lav7f5K gMXVeF6eQ+T1O6likosxRmJhlrMRcWJADxL1DvOAgAA X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-16.tower-31.messagelabs.com!1473340284!52061530!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 47174 invoked from network); 8 Sep 2016 13:11:26 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-16.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 8 Sep 2016 13:11:26 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Thu, 08 Sep 2016 07:11:24 -0600 Message-Id: <57D17F9D020000780010D160@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.1 Date: Thu, 08 Sep 2016 07:11:25 -0600 From: "Jan Beulich" To: "xen-devel" References: <57D17C78020000780010D127@prv-mh.provo.novell.com> In-Reply-To: <57D17C78020000780010D127@prv-mh.provo.novell.com> Mime-Version: 1.0 Cc: Andrew Cooper Subject: [Xen-devel] [PATCH 05/17] x86emul: add XOP decoding 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 This way we can at least size (and e.g. skip) them if needed, and we also won't raise the wrong fault due to not having read all relevant bytes. Signed-off-by: Jan Beulich x86emul: add XOP decoding This way we can at least size (and e.g. skip) them if needed, and we also won't raise the wrong fault due to not having read all relevant bytes. Signed-off-by: Jan Beulich --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -279,6 +279,12 @@ static const opcode_desc_t twobyte_table ModRM, ModRM, ModRM, ModRM, ModRM, ModRM, ModRM, ModRM }; +static const opcode_desc_t xop_table[] = { + DstReg|SrcImmByte|ModRM, + DstReg|SrcMem|ModRM, + DstReg|SrcImm|ModRM, +}; + #define REX_PREFIX 0x40 #define REX_B 0x01 #define REX_X 0x02 @@ -1580,6 +1586,9 @@ struct x86_emulate_state { ext_0f = vex_0f, ext_0f38 = vex_0f38, ext_0f3a = vex_0f3a, + ext_8f08 = 8, + ext_8f09, + ext_8f0a, } ext; uint8_t opcode; uint8_t modrm, modrm_mod, modrm_reg, modrm_rm; @@ -1802,7 +1811,7 @@ x86_decode( modrm = insn_fetch_type(uint8_t); modrm_mod = (modrm & 0xc0) >> 6; - if ( !ext && ((b & ~1) == 0xc4) ) + if ( !ext && ((b & ~1) == 0xc4 || (b == 0x8f && (modrm & 0x18))) ) switch ( def_ad_bytes ) { default: @@ -1816,11 +1825,11 @@ x86_decode( break; /* fall through */ case 8: - /* VEX */ + /* VEX / XOP */ generate_exception_if(rex_prefix || vex.pfx, EXC_UD, -1); vex.raw[0] = modrm; - if ( b & 1 ) + if ( b == 0xc5 ) { vex.raw[1] = modrm; vex.opcx = vex_0f; @@ -1848,18 +1857,30 @@ x86_decode( rex_prefix |= REX_R; b = insn_fetch_type(uint8_t); - switch ( ext = vex.opcx ) + ext = vex.opcx; + if ( b != 0x8f ) + { + switch ( ext ) + { + case vex_0f: + d = twobyte_table[b]; + break; + case vex_0f38: + d = twobyte_table[0x38]; + break; + case vex_0f3a: + d = twobyte_table[0x3a]; + break; + default: + rc = X86EMUL_UNHANDLEABLE; + goto done; + } + } + else if ( ext < ext_8f08 + + sizeof(xop_table) / sizeof(*xop_table) ) + d = xop_table[ext - ext_8f08]; + else { - case vex_0f: - d = twobyte_table[b]; - break; - case vex_0f38: - d = twobyte_table[0x38]; - break; - case vex_0f3a: - d = twobyte_table[0x3a]; - break; - default: rc = X86EMUL_UNHANDLEABLE; goto done; } @@ -1921,6 +1942,9 @@ x86_decode( case ext_0f: case ext_0f3a: + case ext_8f08: + case ext_8f09: + case ext_8f0a: break; case ext_0f38: @@ -2112,6 +2136,9 @@ x86_decode( case ext_0f38: case ext_0f3a: + case ext_8f08: + case ext_8f09: + case ext_8f0a: break; default: @@ -2332,6 +2359,9 @@ x86_emulate( default: ASSERT_UNREACHABLE(); case ext_0f3a: + case ext_8f08: + case ext_8f09: + case ext_8f0a: goto cannot_emulate; } --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -279,6 +279,12 @@ static const opcode_desc_t twobyte_table ModRM, ModRM, ModRM, ModRM, ModRM, ModRM, ModRM, ModRM }; +static const opcode_desc_t xop_table[] = { + DstReg|SrcImmByte|ModRM, + DstReg|SrcMem|ModRM, + DstReg|SrcImm|ModRM, +}; + #define REX_PREFIX 0x40 #define REX_B 0x01 #define REX_X 0x02 @@ -1580,6 +1586,9 @@ struct x86_emulate_state { ext_0f = vex_0f, ext_0f38 = vex_0f38, ext_0f3a = vex_0f3a, + ext_8f08 = 8, + ext_8f09, + ext_8f0a, } ext; uint8_t opcode; uint8_t modrm, modrm_mod, modrm_reg, modrm_rm; @@ -1802,7 +1811,7 @@ x86_decode( modrm = insn_fetch_type(uint8_t); modrm_mod = (modrm & 0xc0) >> 6; - if ( !ext && ((b & ~1) == 0xc4) ) + if ( !ext && ((b & ~1) == 0xc4 || (b == 0x8f && (modrm & 0x18))) ) switch ( def_ad_bytes ) { default: @@ -1816,11 +1825,11 @@ x86_decode( break; /* fall through */ case 8: - /* VEX */ + /* VEX / XOP */ generate_exception_if(rex_prefix || vex.pfx, EXC_UD, -1); vex.raw[0] = modrm; - if ( b & 1 ) + if ( b == 0xc5 ) { vex.raw[1] = modrm; vex.opcx = vex_0f; @@ -1848,18 +1857,30 @@ x86_decode( rex_prefix |= REX_R; b = insn_fetch_type(uint8_t); - switch ( ext = vex.opcx ) + ext = vex.opcx; + if ( b != 0x8f ) + { + switch ( ext ) + { + case vex_0f: + d = twobyte_table[b]; + break; + case vex_0f38: + d = twobyte_table[0x38]; + break; + case vex_0f3a: + d = twobyte_table[0x3a]; + break; + default: + rc = X86EMUL_UNHANDLEABLE; + goto done; + } + } + else if ( ext < ext_8f08 + + sizeof(xop_table) / sizeof(*xop_table) ) + d = xop_table[ext - ext_8f08]; + else { - case vex_0f: - d = twobyte_table[b]; - break; - case vex_0f38: - d = twobyte_table[0x38]; - break; - case vex_0f3a: - d = twobyte_table[0x3a]; - break; - default: rc = X86EMUL_UNHANDLEABLE; goto done; } @@ -1921,6 +1942,9 @@ x86_decode( case ext_0f: case ext_0f3a: + case ext_8f08: + case ext_8f09: + case ext_8f0a: break; case ext_0f38: @@ -2112,6 +2136,9 @@ x86_decode( case ext_0f38: case ext_0f3a: + case ext_8f08: + case ext_8f09: + case ext_8f0a: break; default: @@ -2332,6 +2359,9 @@ x86_emulate( default: ASSERT_UNREACHABLE(); case ext_0f3a: + case ext_8f08: + case ext_8f09: + case ext_8f0a: goto cannot_emulate; }