target/i386: split X86_CHECK_prot into PE and VM86 checks

SYSENTER is allowed in VM86 mode, but not in real mode.  Split the check
so that PE and !VM86 are covered by separate bits.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2024-05-09 09:52:30 +02:00
parent ea89aa895e
commit 556c4c5cc4
2 changed files with 13 additions and 4 deletions

View File

@ -2566,8 +2566,13 @@ static void disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op; goto illegal_op;
} }
} }
if (decode.e.check & X86_CHECK_prot) { if (decode.e.check & X86_CHECK_prot_or_vm86) {
if (!PE(s) || VM86(s)) { if (!PE(s)) {
goto illegal_op;
}
}
if (decode.e.check & X86_CHECK_no_vm86) {
if (VM86(s)) {
goto illegal_op; goto illegal_op;
} }
} }

View File

@ -150,8 +150,8 @@ typedef enum X86InsnCheck {
X86_CHECK_i64 = 1, X86_CHECK_i64 = 1,
X86_CHECK_o64 = 2, X86_CHECK_o64 = 2,
/* Fault outside protected mode */ /* Fault in vm86 mode */
X86_CHECK_prot = 4, X86_CHECK_no_vm86 = 4,
/* Privileged instruction checks */ /* Privileged instruction checks */
X86_CHECK_cpl0 = 8, X86_CHECK_cpl0 = 8,
@ -167,6 +167,10 @@ typedef enum X86InsnCheck {
/* Fault if VEX.W=0 */ /* Fault if VEX.W=0 */
X86_CHECK_W1 = 256, 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; } X86InsnCheck;
typedef enum X86InsnSpecial { typedef enum X86InsnSpecial {