From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: [PATCH 05/17] x86emul: add XOP decoding Date: Thu, 08 Sep 2016 07:11:25 -0600 Message-ID: <57D17F9D020000780010D160@prv-mh.provo.novell.com> References: <57D17C78020000780010D127@prv-mh.provo.novell.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__PartE0D66B6D.1__=" Return-path: 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 In-Reply-To: <57D17C78020000780010D127@prv-mh.provo.novell.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" To: xen-devel Cc: Andrew Cooper List-Id: xen-devel@lists.xenproject.org This is a MIME message. If you are reading this text, you may want to consider changing to a mail reader or gateway that understands how to properly handle MIME multipart messages. --=__PartE0D66B6D.1__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline 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 }; =20 +static const opcode_desc_t xop_table[] =3D { + 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 =3D vex_0f, ext_0f38 =3D vex_0f38, ext_0f3a =3D vex_0f3a, + ext_8f08 =3D 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 =3D insn_fetch_type(uint8_t); modrm_mod =3D (modrm & 0xc0) >> 6; =20 - if ( !ext && ((b & ~1) =3D=3D 0xc4) ) + if ( !ext && ((b & ~1) =3D=3D 0xc4 || (b =3D=3D 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); =20 vex.raw[0] =3D modrm; - if ( b & 1 ) + if ( b =3D=3D 0xc5 ) { vex.raw[1] =3D modrm; vex.opcx =3D vex_0f; @@ -1848,18 +1857,30 @@ x86_decode( rex_prefix |=3D REX_R; =20 b =3D insn_fetch_type(uint8_t); - switch ( ext =3D vex.opcx ) + ext =3D vex.opcx; + if ( b !=3D 0x8f ) + { + switch ( ext ) + { + case vex_0f: + d =3D twobyte_table[b]; + break; + case vex_0f38: + d =3D twobyte_table[0x38]; + break; + case vex_0f3a: + d =3D twobyte_table[0x3a]; + break; + default: + rc =3D X86EMUL_UNHANDLEABLE; + goto done; + } + } + else if ( ext < ext_8f08 + + sizeof(xop_table) / sizeof(*xop_table) ) + d =3D xop_table[ext - ext_8f08]; + else { - case vex_0f: - d =3D twobyte_table[b]; - break; - case vex_0f38: - d =3D twobyte_table[0x38]; - break; - case vex_0f3a: - d =3D twobyte_table[0x3a]; - break; - default: rc =3D X86EMUL_UNHANDLEABLE; goto done; } @@ -1921,6 +1942,9 @@ x86_decode( =20 case ext_0f: case ext_0f3a: + case ext_8f08: + case ext_8f09: + case ext_8f0a: break; =20 case ext_0f38: @@ -2112,6 +2136,9 @@ x86_decode( =20 case ext_0f38: case ext_0f3a: + case ext_8f08: + case ext_8f09: + case ext_8f0a: break; =20 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; } =20 --=__PartE0D66B6D.1__= Content-Type: text/plain; name="x86emul-decode-XOP.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="x86emul-decode-XOP.patch" x86emul: add XOP decoding=0A=0AThis way we can at least size (and e.g. = skip) them if needed, and we=0Aalso won't raise the wrong fault due to not = having read all relevant=0Abytes.=0A=0ASigned-off-by: Jan Beulich = =0A=0A--- a/xen/arch/x86/x86_emulate/x86_emulate.c=0A+++= b/xen/arch/x86/x86_emulate/x86_emulate.c=0A@@ -279,6 +279,12 @@ static = const opcode_desc_t twobyte_table=0A ModRM, ModRM, ModRM, ModRM, = ModRM, ModRM, ModRM, ModRM=0A };=0A =0A+static const opcode_desc_t = xop_table[] =3D {=0A+ DstReg|SrcImmByte|ModRM,=0A+ DstReg|SrcMem|ModR= M,=0A+ DstReg|SrcImm|ModRM,=0A+};=0A+=0A #define REX_PREFIX 0x40=0A = #define REX_B 0x01=0A #define REX_X 0x02=0A@@ -1580,6 +1586,9 @@ struct = x86_emulate_state {=0A ext_0f =3D vex_0f,=0A ext_0f38 = =3D vex_0f38,=0A ext_0f3a =3D vex_0f3a,=0A+ ext_8f08 =3D = 8,=0A+ ext_8f09,=0A+ ext_8f0a,=0A } ext;=0A uint8_t = opcode;=0A uint8_t modrm, modrm_mod, modrm_reg, modrm_rm;=0A@@ -1802,7 = +1811,7 @@ x86_decode(=0A modrm =3D insn_fetch_type(uint8_t);=0A = modrm_mod =3D (modrm & 0xc0) >> 6;=0A =0A- if ( !ext && ((b & = ~1) =3D=3D 0xc4) )=0A+ if ( !ext && ((b & ~1) =3D=3D 0xc4 || (b = =3D=3D 0x8f && (modrm & 0x18))) )=0A switch ( def_ad_bytes = )=0A {=0A default:=0A@@ -1816,11 +1825,11 @@ = x86_decode(=0A break;=0A /* fall = through */=0A case 8:=0A- /* VEX */=0A+ = /* VEX / XOP */=0A generate_exception_if(rex_prefix = || vex.pfx, EXC_UD, -1);=0A =0A vex.raw[0] =3D modrm;=0A- = if ( b & 1 )=0A+ if ( b =3D=3D 0xc5 )=0A = {=0A vex.raw[1] =3D modrm;=0A = vex.opcx =3D vex_0f;=0A@@ -1848,18 +1857,30 @@ x86_decode(=0A = rex_prefix |=3D REX_R;=0A =0A b =3D insn_fetch= _type(uint8_t);=0A- switch ( ext =3D vex.opcx )=0A+ = ext =3D vex.opcx;=0A+ if ( b !=3D 0x8f )=0A+ = {=0A+ switch ( ext )=0A+ = {=0A+ case vex_0f:=0A+ d =3D = twobyte_table[b];=0A+ break;=0A+ = case vex_0f38:=0A+ d =3D twobyte_table[0x38];=0A+ = break;=0A+ case vex_0f3a:=0A+ = d =3D twobyte_table[0x3a];=0A+ = break;=0A+ default:=0A+ rc =3D = X86EMUL_UNHANDLEABLE;=0A+ goto done;=0A+ = }=0A+ }=0A+ else if ( ext < ext_8f08 = +=0A+ sizeof(xop_table) / sizeof(*xop_table)= )=0A+ d =3D xop_table[ext - ext_8f08];=0A+ = else=0A {=0A- case vex_0f:=0A- = d =3D twobyte_table[b];=0A- break;=0A- = case vex_0f38:=0A- d =3D twobyte_table[0x38];=0A-= break;=0A- case vex_0f3a:=0A- = d =3D twobyte_table[0x3a];=0A- break;=0A- = default:=0A rc =3D X86EMUL_UNHANDLEABLE;=0A = goto done;=0A }=0A@@ -1921,6 +1942,9 @@ = x86_decode(=0A =0A case ext_0f:=0A case ext_0f3a:=0A+ = case ext_8f08:=0A+ case ext_8f09:=0A+ case ext_8f0a:=0A = break;=0A =0A case ext_0f38:=0A@@ -2112,6 +2136,9 @@ = x86_decode(=0A =0A case ext_0f38:=0A case ext_0f3a:=0A+ case = ext_8f08:=0A+ case ext_8f09:=0A+ case ext_8f0a:=0A break;=0A = =0A default:=0A@@ -2332,6 +2359,9 @@ x86_emulate(=0A default:=0A = ASSERT_UNREACHABLE();=0A case ext_0f3a:=0A+ case ext_8f08:=0A+= case ext_8f09:=0A+ case ext_8f0a:=0A goto cannot_emulate;=0A= }=0A =0A --=__PartE0D66B6D.1__= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KWGVuLWRldmVs IG1haWxpbmcgbGlzdApYZW4tZGV2ZWxAbGlzdHMueGVuLm9yZwpodHRwczovL2xpc3RzLnhlbi5v cmcveGVuLWRldmVsCg== --=__PartE0D66B6D.1__=--