|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 13/30] x86emul: switch to EVEX.X3 nomenclature
The APX spec renames the X field and repurposes U for the 5th index
register bit; it can be expected for the SDM to follow once APX stuff is
folded in. The new naming is also better to reflect in our structure
field identifiers.
Like we represent VEX.X and EVEX.X3 in rex_prefix, also represent
EVEX.U (EVEX.X4) in rex2_prefix, allowing to leave index register
calculation untouched.
In the test harness'es evex-disp8.c also rename the "mbs" field at this
occasion.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
--- a/tools/tests/x86_emulator/evex-disp8.c
+++ b/tools/tests/x86_emulator/evex-disp8.c
@@ -941,10 +941,10 @@ static void test_one(const struct test *
uint8_t b4:1;
uint8_t r4:1;
uint8_t b3:1;
- uint8_t x:1;
+ uint8_t x3:1;
uint8_t r3:1;
uint8_t pfx:2;
- uint8_t mbs:1;
+ uint8_t u:1;
uint8_t reg:4;
uint8_t w:1;
uint8_t opmsk:3;
@@ -955,7 +955,7 @@ static void test_one(const struct test *
};
} evex = {
.opcx = test->spc, .pfx = test->pfx, .lr = vl,
- .r4 = 1, .b3 = 1, .x = 1, .r3 = 1, .mbs = 1,
+ .r4 = 1, .b3 = 1, .x3 = 1, .r3 = 1, .u = 1,
.reg = 0xf, .RX = 1, .opmsk = sg,
};
--- a/xen/arch/x86/x86_emulate/decode.c
+++ b/xen/arch/x86/x86_emulate/decode.c
@@ -16,7 +16,7 @@
# define ERR_PTR(val) NULL
#endif
-#define evex_encoded() (s->evex.mbs)
+#define evex_encoded() (s->evex.opcx)
struct x86_emulate_state *
x86_decode_insn(
@@ -1276,7 +1276,20 @@ int x86emul_decode(struct x86_emulate_st
s->evex.raw[1] = s->vex.raw[1];
s->evex.raw[2] = insn_fetch_type(uint8_t);
- generate_exception_if(!s->evex.mbs, X86_EXC_UD);
+ /*
+ * VEX.L's bit position matches EVEX.U. Shared code
+ * paths for vector insns use evex.lr (copying happens
+ * a little further down), but the bit being set can
+ * get in the way on shared APX code paths.
+ */
+ s->vex.l = 0;
+
+ /*
+ * .opcx is being checked here just to be on the safe
+ * side, especially as long as evex_encoded() uses
+ * this field.
+ */
+ generate_exception_if(!s->evex.opcx, X86_EXC_UD);
generate_exception_if((!(s->xcr0 & X86_XCR0_APX) &&
s->evex.b4),
X86_EXC_UD);
@@ -1293,6 +1306,8 @@ int x86emul_decode(struct x86_emulate_st
s->rex2_prefix |= REX_R;
if ( s->evex.b4 )
s->rex2_prefix |= REX_B;
+ if ( !s->evex.u )
+ s->rex2_prefix |= REX_X;
}
s->vex.opcx = s->evex.opcx;
@@ -1535,7 +1550,11 @@ int x86emul_decode(struct x86_emulate_st
if ( ext0f38_table[b].two_op )
d |= TwoOp;
if ( ext0f38_table[b].vsib )
+ {
+ generate_exception_if(evex_encoded() && !s->evex.u,
+ X86_EXC_UD);
d |= vSIB;
+ }
s->simd_size = ext0f38_table[b].simd_size;
if ( evex_encoded() )
{
@@ -1898,7 +1917,7 @@ int x86emul_decode(struct x86_emulate_st
generate_exception_if(d & vSIB, X86_EXC_UD);
s->modrm_rm |= ((s->rex_prefix & 1) << 3) |
((evex_encoded() && !rm_is_gpr
- ? !s->evex.x
+ ? !s->evex.x3
: !!(s->rex2_prefix & REX_B)) << 4);
s->ea.type = OP_REG;
}
@@ -2038,6 +2057,16 @@ int x86emul_decode(struct x86_emulate_st
if ( override_seg != x86_seg_none )
s->ea.mem.seg = override_seg;
+ /*
+ * While this generic check takes care of most insns, scalar ones (with
+ * EVEX.b set) need checking individually (elsewhere).
+ */
+ generate_exception_if((evex_encoded() &&
+ !s->evex.u &&
+ (s->modrm_mod == 3 ||
+ !(s->xcr0 & X86_XCR0_APX))),
+ X86_EXC_UD);
+
/* Fetch the immediate operand, if present. */
switch ( d & SrcMask )
{
--- a/xen/arch/x86/x86_emulate/private.h
+++ b/xen/arch/x86/x86_emulate/private.h
@@ -239,10 +239,10 @@ union evex {
uint8_t b4:1; /* B4 */
uint8_t r4:1; /* R4 (aka R') */
uint8_t b3:1; /* B3 (aka B) */
- uint8_t x:1; /* X */
+ uint8_t x3:1; /* X3 (aka X) */
uint8_t r3:1; /* R3 (aka R) */
uint8_t pfx:2; /* pp */
- uint8_t mbs:1;
+ uint8_t u:1; /* U (aka X4) */
uint8_t reg:4; /* vvvv */
uint8_t w:1; /* W */
uint8_t opmsk:3; /* aaa */
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -1302,7 +1302,7 @@ int cf_check x86emul_unhandleable_rw(
#define lock_prefix (state->lock_prefix)
#define vex (state->vex)
#define evex (state->evex)
-#define evex_encoded() (evex.mbs)
+#define evex_encoded() (evex.opcx)
#define ea (state->ea)
/* Undo DEBUG wrapper. */
@@ -7529,7 +7529,7 @@ x86_emulate(
b = 0x15;
modrm <<= 3;
evex.r3 = evex.b3;
- evex.r4 = evex.x;
+ evex.r4 = evex.x3;
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x14): /* vpextrb $imm8,xmm,r/m */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x15): /* vpextrw $imm8,xmm,r/m */
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |