diff mbox series

[kvm-unit-tests,v3,3/7] x86: Introduce ASM_TRY_FEP() to handle exceptions on forced emulation

Message ID 20220808164707.537067-4-seanjc@google.com (mailing list archive)
State New, archived
Headers show
Series x86: Illegal LEA test and FEP cleanups | expand

Commit Message

Sean Christopherson Aug. 8, 2022, 4:47 p.m. UTC
From: Michal Luczaj <mhal@rbox.co>

Introduce ASM_TRY_FEP() to allow using the try-catch method to handle
exceptions that occur on forced emulation.  ASM_TRY() mishandles
exceptions thrown by the forced-emulation-triggered emulator. While the
faulting address stored in the exception table points at forced emulation
prefix, when an exceptions comes, RIP is 5 bytes (size of KVM_FEP) ahead
due to KVM advancing RIP to skip the prefix and the exception ends up
unhandled.

Signed-off-by: Michal Luczaj <mhal@rbox.co>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 lib/x86/desc.h | 13 ++++++++++---
 x86/emulator.c |  1 -
 x86/pmu.c      |  1 -
 3 files changed, 10 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/lib/x86/desc.h b/lib/x86/desc.h
index 10ba8cb..8f708fd 100644
--- a/lib/x86/desc.h
+++ b/lib/x86/desc.h
@@ -92,13 +92,20 @@  typedef struct  __attribute__((packed)) {
 	u16 iomap_base;
 } tss64_t;
 
-#define ASM_TRY(catch)						\
-	"movl $0, %%gs:4 \n\t"					\
-	".pushsection .data.ex \n\t"				\
+#define __ASM_TRY(prefix, catch)				\
+	"movl $0, %%gs:4\n\t"					\
+	".pushsection .data.ex\n\t"				\
 	__ASM_SEL(.long, .quad) " 1111f,  " catch "\n\t"	\
 	".popsection \n\t"					\
+	prefix "\n\t"						\
 	"1111:"
 
+#define ASM_TRY(catch) __ASM_TRY("", catch)
+
+/* Forced emulation prefix, used to invoke the emulator unconditionally. */
+#define KVM_FEP "ud2; .byte 'k', 'v', 'm';"
+#define ASM_TRY_FEP(catch) __ASM_TRY(KVM_FEP, catch)
+
 /*
  * selector     32-bit                        64-bit
  * 0x00         NULL descriptor               NULL descriptor
diff --git a/x86/emulator.c b/x86/emulator.c
index 769a049..6dc88f1 100644
--- a/x86/emulator.c
+++ b/x86/emulator.c
@@ -18,7 +18,6 @@ 
 static int exceptions;
 
 /* 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;
 
diff --git a/x86/pmu.c b/x86/pmu.c
index 01be1e9..457c5b9 100644
--- a/x86/pmu.c
+++ b/x86/pmu.c
@@ -33,7 +33,6 @@ 
 
 #define N 1000000
 
-#define KVM_FEP "ud2; .byte 'k', 'v', 'm';"
 // These values match the number of instructions and branches in the
 // assembly block in check_emulated_instr().
 #define EXPECTED_INSTR 17