For #UD handling use ASM_TRY() instead of handle_exception(). Suggested-by: Sean Christopherson <seanjc@xxxxxxxxxx> Signed-off-by: Michal Luczaj <mhal@xxxxxxx> --- v1 -> v2: Change `mov` to `movl` to silence the compiler warning x86/emulator.c | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/x86/emulator.c b/x86/emulator.c index 769a049..96d3ccd 100644 --- a/x86/emulator.c +++ b/x86/emulator.c @@ -17,10 +17,8 @@ static int exceptions; -/* Forced emulation prefix, used to invoke the emulator unconditionally. */ +/* Forced emulation prefix, used to invoke the emulator unconditionally. */ #define KVM_FEP "ud2; .byte 'k', 'v', 'm';" -#define KVM_FEP_LENGTH 5 -static int fep_available = 1; struct regs { u64 rax, rbx, rcx, rdx; @@ -1099,33 +1097,23 @@ static void test_simplealu(u32 *mem) report(*mem == 0x8400, "test"); } -static void illegal_movbe_handler(struct ex_regs *regs) -{ - extern char bad_movbe_cont; - - ++exceptions; - regs->rip = (ulong)&bad_movbe_cont; -} - static void test_illegal_movbe(void) { + unsigned int vector; + if (!this_cpu_has(X86_FEATURE_MOVBE)) { - report_skip("illegal movbe"); + report_skip("MOVBE unsupported by CPU"); return; } - exceptions = 0; - handle_exception(UD_VECTOR, illegal_movbe_handler); - asm volatile(".byte 0x0f; .byte 0x38; .byte 0xf0; .byte 0xc0;\n\t" - " bad_movbe_cont:" : : : "rax"); - report(exceptions == 1, "illegal movbe"); - handle_exception(UD_VECTOR, 0); -} + asm volatile(ASM_TRY("1f") + ".byte 0x0f; .byte 0x38; .byte 0xf0; .byte 0xc0;\n\t" + "1:" + : : : "memory", "rax"); -static void record_no_fep(struct ex_regs *regs) -{ - fep_available = 0; - regs->rip += KVM_FEP_LENGTH; + vector = exception_vector(); + report(vector == UD_VECTOR, + "Wanted #UD on MOVBE with /reg, got vector = %u", vector); } int main(void) @@ -1135,11 +1123,13 @@ int main(void) void *insn_ram; void *cross_mem; unsigned long t1, t2; + int fep_available = 0; setup_vm(); - handle_exception(UD_VECTOR, record_no_fep); - asm(KVM_FEP "nop"); - handle_exception(UD_VECTOR, 0); + asm volatile(ASM_TRY("1f") + KVM_FEP "movl $1, %[fep_available]\n\t" + "1:" + : [fep_available] "=m" (fep_available) : : "memory"); mem = alloc_vpages(2); install_page((void *)read_cr3(), IORAM_BASE_PHYS, mem); -- 2.37.1