diff mbox series

[kvm-unit-tests,v2,15/16] x86/emulator64: Switch test_mmx_movq_mf() to ASM_TRY()

Message ID 20230413184219.36404-16-minipli@grsecurity.net (mailing list archive)
State New, archived
Headers show
Series x86: cleanups, fixes and new tests | expand

Commit Message

Mathias Krause April 13, 2023, 6:42 p.m. UTC
Drop the last user of the one-off exception handler by making use of
ASM_TRY() for the #MF test.

Also streamline the multiple scattered asm() statements into a single
one making use of a real output value instead of hard-coding rax and
relying on the instruction to generate an exception (instead of
clobbering rax and not making gcc aware of it).

As this removes the last user of advance_rip_and_note_exception() we can
remove it for good!

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
---
 x86/emulator64.c | 39 ++++++++++++++++-----------------------
 1 file changed, 16 insertions(+), 23 deletions(-)
diff mbox series

Patch

diff --git a/x86/emulator64.c b/x86/emulator64.c
index 50a02bca6ac8..f8ff99fc39cc 100644
--- a/x86/emulator64.c
+++ b/x86/emulator64.c
@@ -1,14 +1,6 @@ 
 #define MAGIC_NUM 0xdeadbeefdeadbeefUL
 #define GS_BASE 0x400000
 
-static unsigned long rip_advance;
-
-static void advance_rip_and_note_exception(struct ex_regs *regs)
-{
-	++exceptions;
-	regs->rip += rip_advance;
-}
-
 static void test_cr8(void)
 {
 	unsigned long src, dst;
@@ -313,23 +305,24 @@  static void test_cmov(u32 *mem)
 
 static void test_mmx_movq_mf(uint64_t *mem)
 {
-	/* movq %mm0, (%rax) */
-	extern char movq_start, movq_end;
-	handler old;
-
 	uint16_t fcw = 0;  /* all exceptions unmasked */
-	write_cr0(read_cr0() & ~6);  /* TS, EM */
-	exceptions = 0;
-	old = handle_exception(MF_VECTOR, advance_rip_and_note_exception);
-	asm volatile("fninit; fldcw %0" : : "m"(fcw));
-	asm volatile("fldz; fldz; fdivp"); /* generate exception */
+	uint64_t val;
 
-	rip_advance = &movq_end - &movq_start;
-	asm(KVM_FEP "movq_start: movq %mm0, (%rax); movq_end:");
-	/* exit MMX mode */
-	asm volatile("fnclex; emms");
-	report(exceptions == 1, "movq mmx generates #MF");
-	handle_exception(MF_VECTOR, old);
+	write_cr0(read_cr0() & ~(X86_CR0_TS | X86_CR0_EM));
+	asm volatile("fninit\n\t"
+		     "fldcw %[fcw]\n\t"
+		     "fldz\n\t"
+		     "fldz\n\t"
+		     /* generate exception (0.0 / 0.0) */
+		     "fdivp\n\t"
+		     /* trigger #MF */
+		     ASM_TRY_FEP("1f") "movq %%mm0, %[val]\n\t"
+		     /* exit MMX mode */
+		     "1: fnclex\n\t"
+		     "emms\n\t"
+		     : [val]"=m"(val)
+		     : [fcw]"m"(fcw));
+	report(exception_vector() == MF_VECTOR, "movq mmx generates #MF");
 }
 
 static void test_jmp_noncanonical(uint64_t *mem)