From patchwork Wed Sep 28 08:10: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: 9353189 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 A6A516077A for ; Wed, 28 Sep 2016 08:12:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 984E329406 for ; Wed, 28 Sep 2016 08:12:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8C6E229409; Wed, 28 Sep 2016 08:12:55 +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 F1CAC29406 for ; Wed, 28 Sep 2016 08:12:54 +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 1bp9x5-0000Kx-73; Wed, 28 Sep 2016 08:10:51 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bp9x3-0000Kl-L5 for xen-devel@lists.xenproject.org; Wed, 28 Sep 2016 08:10:49 +0000 Received: from [85.158.143.35] by server-5.bemta-6.messagelabs.com id E9/72-29563-90B7BE75; Wed, 28 Sep 2016 08:10:49 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrNIsWRWlGSWpSXmKPExsXS6fjDS5ej+nW 4wbHDIhbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8bDa/uZCxaZVMz+PoetgfGVchcjJ4eQQJ7E 7m8zWUFsXgE7iVun9zGB2BIChhJP319nA7FZBFQlru86wgJiswmoS7Q92w5Uz8EhImAgce5oE ojJLKAvsW0dWIWwgInEvPfvWCGm20k8fv0GLM4pYC/x9doXsE5eAUGJvzuEQcLMQCXHNn1ins DIMwshMwtJBsLWknj46xYLhK0tsWzha+ZZYHulJZb/44AIW0ms6v/EiqoExHaVWLL+C9sCRo5 VjOrFqUVlqUW6lnpJRZnpGSW5iZk5uoYGZnq5qcXFiempOYlJxXrJ+bmbGIGBygAEOxjvbgo4 xCjJwaQkyrs5/HW4EF9SfkplRmJxRnxRaU5q8SFGGQ4OJQne45VAOcGi1PTUirTMHGDMwKQlO HiURHjdQdK8xQWJucWZ6RCpU4yKUuK8TyqAEgIgiYzSPLg2WJxeYpSVEuZlBDpEiKcgtSg3sw RV/hWjOAejkjAvQxXQFJ7MvBK46a+AFjMBLV564gXI4pJEhJRUA6PixMuTNuccNpwxvcvT4OO FA1k/dvNMDVT6pt++57VFzPWIT/Jl690yRHbpq+RXJ9y7F6PtG3G9627F+qMO6x/9ubE65s+v 6Fsb5zNtf/PnkPeDap//qhvs0rekhX6a7sD8dZpdi93E3F+x/wuPV/yI+q2RMO1t/iGXZWXVN vPX+V0ziOo0016txFKckWioxVxUnAgApai55M4CAAA= X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-7.tower-21.messagelabs.com!1475050246!35447814!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 2464 invoked from network); 28 Sep 2016 08:10:48 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-7.tower-21.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 28 Sep 2016 08:10:48 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Wed, 28 Sep 2016 02:10:24 -0600 Message-Id: <57EB970F02000078001131C3@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.1 Date: Wed, 28 Sep 2016 02:10:23 -0600 From: "Jan Beulich" To: "xen-devel" References: <57EB94940200007800113179@prv-mh.provo.novell.com> In-Reply-To: <57EB94940200007800113179@prv-mh.provo.novell.com> Mime-Version: 1.0 Cc: Andrew Cooper Subject: [Xen-devel] [PATCH v2 06/16] x86emul: add EVEX 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 Reviewed-by: Andrew Cooper --- TBD: I'm kind of undecided whether to right away propagate evex.R into modrm_reg (and then also deal with the new meaning of evex.x for modrm_rm). Since that doesn't affect GPRs (and the extra bits would need masking off when accessing GPRs) I've left this out for now. x86emul: add EVEX 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 --- TBD: I'm kind of undecided whether to right away propagate evex.R into modrm_reg (and then also deal with the new meaning of evex.x for modrm_rm). Since that doesn't affect GPRs (and the extra bits would need masking off when accessing GPRs) I've left this out for now. --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -336,6 +336,27 @@ union vex { ptr[1] = rex | REX_PREFIX; \ } while (0) +union evex { + uint8_t raw[3]; + struct { + uint8_t opcx:2; + uint8_t :2; + uint8_t R:1; + uint8_t b:1; + uint8_t x:1; + uint8_t r:1; + uint8_t pfx:2; + uint8_t evex:1; + uint8_t reg:4; + uint8_t w:1; + uint8_t opmsk:3; + uint8_t RX:1; + uint8_t bcst:1; + uint8_t lr:2; + uint8_t z:1; + }; +}; + #define rep_prefix() (vex.pfx >= vex_f3) #define repe_prefix() (vex.pfx == vex_f3) #define repne_prefix() (vex.pfx == vex_f2) @@ -1611,6 +1632,7 @@ struct x86_emulate_state { bool lock_prefix; opcode_desc_t desc; union vex vex; + union evex evex; int override_seg; /* @@ -1638,6 +1660,7 @@ struct x86_emulate_state { #define rex_prefix (state->rex_prefix) #define lock_prefix (state->lock_prefix) #define vex (state->vex) +#define evex (state->evex) #define override_seg (state->override_seg) #define ea (state->ea) @@ -1826,7 +1849,8 @@ x86_decode( modrm = insn_fetch_type(uint8_t); modrm_mod = (modrm & 0xc0) >> 6; - if ( !ext && ((b & ~1) == 0xc4 || (b == 0x8f && (modrm & 0x18))) ) + if ( !ext && ((b & ~1) == 0xc4 || (b == 0x8f && (modrm & 0x18)) || + b == 0x62) ) switch ( def_ad_bytes ) { default: @@ -1840,7 +1864,7 @@ x86_decode( break; /* fall through */ case 8: - /* VEX / XOP */ + /* VEX / XOP / EVEX */ generate_exception_if(rex_prefix || vex.pfx, EXC_UD, -1); vex.raw[0] = modrm; @@ -1867,6 +1891,14 @@ x86_decode( op_bytes = 8; } } + if ( b == 0x62 ) + { + evex.raw[0] = vex.raw[0]; + evex.raw[1] = vex.raw[1]; + evex.raw[2] = insn_fetch_type(uint8_t); + + vex.opcx = evex.opcx; + } } if ( mode_64bit() && !vex.r ) rex_prefix |= REX_R; --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -336,6 +336,27 @@ union vex { ptr[1] = rex | REX_PREFIX; \ } while (0) +union evex { + uint8_t raw[3]; + struct { + uint8_t opcx:2; + uint8_t :2; + uint8_t R:1; + uint8_t b:1; + uint8_t x:1; + uint8_t r:1; + uint8_t pfx:2; + uint8_t evex:1; + uint8_t reg:4; + uint8_t w:1; + uint8_t opmsk:3; + uint8_t RX:1; + uint8_t bcst:1; + uint8_t lr:2; + uint8_t z:1; + }; +}; + #define rep_prefix() (vex.pfx >= vex_f3) #define repe_prefix() (vex.pfx == vex_f3) #define repne_prefix() (vex.pfx == vex_f2) @@ -1611,6 +1632,7 @@ struct x86_emulate_state { bool lock_prefix; opcode_desc_t desc; union vex vex; + union evex evex; int override_seg; /* @@ -1638,6 +1660,7 @@ struct x86_emulate_state { #define rex_prefix (state->rex_prefix) #define lock_prefix (state->lock_prefix) #define vex (state->vex) +#define evex (state->evex) #define override_seg (state->override_seg) #define ea (state->ea) @@ -1826,7 +1849,8 @@ x86_decode( modrm = insn_fetch_type(uint8_t); modrm_mod = (modrm & 0xc0) >> 6; - if ( !ext && ((b & ~1) == 0xc4 || (b == 0x8f && (modrm & 0x18))) ) + if ( !ext && ((b & ~1) == 0xc4 || (b == 0x8f && (modrm & 0x18)) || + b == 0x62) ) switch ( def_ad_bytes ) { default: @@ -1840,7 +1864,7 @@ x86_decode( break; /* fall through */ case 8: - /* VEX / XOP */ + /* VEX / XOP / EVEX */ generate_exception_if(rex_prefix || vex.pfx, EXC_UD, -1); vex.raw[0] = modrm; @@ -1867,6 +1891,14 @@ x86_decode( op_bytes = 8; } } + if ( b == 0x62 ) + { + evex.raw[0] = vex.raw[0]; + evex.raw[1] = vex.raw[1]; + evex.raw[2] = insn_fetch_type(uint8_t); + + vex.opcx = evex.opcx; + } } if ( mode_64bit() && !vex.r ) rex_prefix |= REX_R;