SYSENTER is allowed in VM86 mode, but not in real mode. Split the check
so that PE and !VM86 are covered by separate bits.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/decode-new.h | 8 ++++++--
target/i386/tcg/decode-new.c.inc | 9 +++++++--
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/target/i386/tcg/decode-new.h b/target/i386/tcg/decode-new.h
index 5577f7509aa..b46a9a0ccb3 100644
--- a/target/i386/tcg/decode-new.h
+++ b/target/i386/tcg/decode-new.h
@@ -149,8 +149,8 @@ typedef enum X86InsnCheck {
X86_CHECK_i64 = 1,
X86_CHECK_o64 = 2,
- /* Fault outside protected mode */
- X86_CHECK_prot = 4,
+ /* Fault in vm86 mode */
+ X86_CHECK_no_vm86 = 4,
/* Privileged instruction checks */
X86_CHECK_cpl0 = 8,
@@ -166,6 +166,10 @@ typedef enum X86InsnCheck {
/* Fault if VEX.W=0 */
X86_CHECK_W1 = 256,
+
+ /* Fault outside protected mode, possibly including vm86 mode */
+ X86_CHECK_prot_or_vm86 = 512,
+ X86_CHECK_prot = X86_CHECK_prot_or_vm86 | X86_CHECK_no_vm86,
} X86InsnCheck;
typedef enum X86InsnSpecial {
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 1c6fa39c3eb..f02f7c62647 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -2558,8 +2558,13 @@ static void disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
}
- if (decode.e.check & X86_CHECK_prot) {
- if (!PE(s) || VM86(s)) {
+ if (decode.e.check & X86_CHECK_prot_or_vm86) {
+ if (!PE(s)) {
+ goto illegal_op;
+ }
+ }
+ if (decode.e.check & X86_CHECK_no_vm86) {
+ if (VM86(s)) {
goto illegal_op;
}
}
--
2.45.1