VSIB instructions (VEX class 12) must not have an address prefix. Checking s->aflag == MO_16 is not enough because in 64-bit mode the address prefix changes aflag to MO_32. Add a specific check bit instead.
Cc: [email protected] Signed-off-by: Paolo Bonzini <[email protected]> --- target/i386/tcg/decode-new.h | 3 +++ target/i386/tcg/decode-new.c.inc | 27 +++++++++++++-------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/target/i386/tcg/decode-new.h b/target/i386/tcg/decode-new.h index 7f23d373ea7..38882b5c6ab 100644 --- a/target/i386/tcg/decode-new.h +++ b/target/i386/tcg/decode-new.h @@ -181,6 +181,9 @@ typedef enum X86InsnCheck { /* Vendor-specific checks for Intel/AMD differences */ X86_CHECK_i64_amd = 2048, X86_CHECK_o64_intel = 4096, + + /* No 0x67 prefix allowed */ + X86_CHECK_no_adr = 8192, } X86InsnCheck; typedef enum X86InsnSpecial { diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index 0f8c5d16938..0b85b0f6513 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc @@ -623,10 +623,10 @@ static const X86OpEntry opcodes_0F38_00toEF[240] = { [0x46] = X86_OP_ENTRY3(VPSRAV, V,x, H,x, W,x, vex6 chk(W0) cpuid(AVX2) p_66), [0x47] = X86_OP_ENTRY3(VPSLLV, V,x, H,x, W,x, vex6 cpuid(AVX2) p_66), - [0x90] = X86_OP_ENTRY3(VPGATHERD, V,x, H,x, M,d, vex12 cpuid(AVX2) p_66), /* vpgatherdd/q */ - [0x91] = X86_OP_ENTRY3(VPGATHERQ, V,x, H,x, M,q, vex12 cpuid(AVX2) p_66), /* vpgatherqd/q */ - [0x92] = X86_OP_ENTRY3(VPGATHERD, V,x, H,x, M,d, vex12 cpuid(AVX2) p_66), /* vgatherdps/d */ - [0x93] = X86_OP_ENTRY3(VPGATHERQ, V,x, H,x, M,q, vex12 cpuid(AVX2) p_66), /* vgatherqps/d */ + [0x90] = X86_OP_ENTRY3(VPGATHERD, V,x, H,x, M,d, vex12 chk(no_adr) cpuid(AVX2) p_66), /* vpgatherdd/q */ + [0x91] = X86_OP_ENTRY3(VPGATHERQ, V,x, H,x, M,q, vex12 chk(no_adr) cpuid(AVX2) p_66), /* vpgatherqd/q */ + [0x92] = X86_OP_ENTRY3(VPGATHERD, V,x, H,x, M,d, vex12 chk(no_adr) cpuid(AVX2) p_66), /* vgatherdps/d */ + [0x93] = X86_OP_ENTRY3(VPGATHERQ, V,x, H,x, M,q, vex12 chk(no_adr) cpuid(AVX2) p_66), /* vgatherqps/d */ /* Should be exception type 2 but they do not have legacy SSE equivalents? */ [0x96] = X86_OP_ENTRY3(VFMADDSUB132Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), @@ -2435,8 +2435,8 @@ static bool validate_vex(DisasContext *s, X86DecodedInsn *decode) break; case 12: /* Must have a VSIB byte and no address prefix. */ - assert(s->has_modrm); - if ((s->modrm & 7) != 4 || s->aflag == MO_16) { + assert(s->has_modrm && (decode->e.check & X86_CHECK_no_adr)); + if ((s->modrm & 7) != 4) { goto illegal; } @@ -2740,15 +2740,14 @@ static void disas_insn(DisasContext *s, CPUState *cpu) goto illegal_op; } } - if (decode.e.check & X86_CHECK_prot_or_vm86) { - if (!PE(s)) { - goto illegal_op; - } + if ((decode.e.check & X86_CHECK_prot_or_vm86) && !PE(s)) { + goto illegal_op; } - if (decode.e.check & X86_CHECK_no_vm86) { - if (VM86(s)) { - goto illegal_op; - } + if ((decode.e.check & X86_CHECK_no_vm86) && VM86(s)) { + goto illegal_op; + } + if ((decode.e.check & X86_CHECK_no_adr) && (s->prefix & PREFIX_ADR)) { + goto illegal_op; } } -- 2.52.0
