kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups
@ 2022-08-08 16:47 Sean Christopherson
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 1/7] x86: emulator.c: Save and restore exception handlers Sean Christopherson
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Sean Christopherson @ 2022-08-08 16:47 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Michal Luczaj

Slightly reworked version of Michal's series clean up the FEP mess and add
a testcase for illegal LEA.  Core ideas are all the same, just moved the
common FEP functionality to desc.h to make it easier to use in other tests.

v3:
 - Define __ASM_SEL/__ASM_FORM in desc.h to fix circular dependency.
 - Move ASM_TRY_FEP() to desc.h
 - Add is_fep_available() helper to simplify probing FEP.
 - Use is_fep_available() in PMU test.

Michal Luczaj (4):
  x86: emulator.c: Save and restore exception handlers
  x86: Introduce ASM_TRY_FEP() to handle exceptions on forced emulation
  x86: emulator.c: Use ASM_TRY() for the UD_VECTOR cases
  x86: Test emulator's handling of LEA with /reg

Sean Christopherson (3):
  x86: Dedup 32-bit vs. 64-bit ASM_TRY() by stealing kernel's
    __ASM_SEL()
  x86: Add helper to detect if forced emulation prefix is available
  x86/pmu: Run the "emulation" test iff forced emulation is available

 lib/x86/desc.h    |  52 ++++++++++++++-----
 x86/emulator.c    | 127 +++++++++++++++++++++++-----------------------
 x86/pmu.c         |  18 +++----
 x86/unittests.cfg |   7 ---
 4 files changed, 110 insertions(+), 94 deletions(-)


base-commit: a106b30d39425b7afbaa3bbd4aab16fd26d333e7
-- 
2.37.1.559.g78731f0fdb-goog


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [kvm-unit-tests PATCH v3 1/7] x86: emulator.c: Save and restore exception handlers
  2022-08-08 16:47 [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups Sean Christopherson
@ 2022-08-08 16:47 ` Sean Christopherson
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 2/7] x86: Dedup 32-bit vs. 64-bit ASM_TRY() by stealing kernel's __ASM_SEL() Sean Christopherson
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sean Christopherson @ 2022-08-08 16:47 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Michal Luczaj

From: Michal Luczaj <mhal@rbox.co>

Users of handle_exception() should always save and restore the handlers.
Leave the #UD cases alone, they will be handled separately by converting
them to ASM_TRY().

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Michal Luczaj <mhal@rbox.co>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 x86/emulator.c | 72 ++++++++++++++++++++++++++------------------------
 1 file changed, 38 insertions(+), 34 deletions(-)

diff --git a/x86/emulator.c b/x86/emulator.c
index cd78e3c..769a049 100644
--- a/x86/emulator.c
+++ b/x86/emulator.c
@@ -710,6 +710,7 @@ static __attribute__((target("sse2"))) void test_sse_exceptions(void *cross_mem)
 	void *page2 = (void *)(&bytes[4096]);
 	struct pte_search search;
 	pteval_t orig_pte;
+	handler old;
 
 	// setup memory for unaligned access
 	mem = (uint32_t *)(&bytes[8]);
@@ -725,10 +726,10 @@ static __attribute__((target("sse2"))) void test_sse_exceptions(void *cross_mem)
 	asm("movupd %1, %0" : "=m"(*mem) : "x"(vv) : "memory");
 	report(sseeq(v, mem), "movupd unaligned");
 	exceptions = 0;
-	handle_exception(GP_VECTOR, unaligned_movaps_handler);
+	old = handle_exception(GP_VECTOR, unaligned_movaps_handler);
 	asm("movaps %1, %0\n\t unaligned_movaps_cont:"
 			: "=m"(*mem) : "x"(vv));
-	handle_exception(GP_VECTOR, 0);
+	handle_exception(GP_VECTOR, old);
 	report(exceptions == 1, "unaligned movaps exception");
 
 	// setup memory for cross page access
@@ -746,10 +747,10 @@ static __attribute__((target("sse2"))) void test_sse_exceptions(void *cross_mem)
 	invlpg(page2);
 
 	exceptions = 0;
-	handle_exception(PF_VECTOR, cross_movups_handler);
+	old = handle_exception(PF_VECTOR, cross_movups_handler);
 	asm("movups %1, %0\n\t cross_movups_cont:" : "=m"(*mem) : "x"(vv) :
 			"memory");
-	handle_exception(PF_VECTOR, 0);
+	handle_exception(PF_VECTOR, old);
 	report(exceptions == 1, "movups crosspage exception");
 
 	// restore invalidated page
@@ -817,36 +818,38 @@ static void advance_rip_and_note_exception(struct ex_regs *regs)
 
 static void test_mmx_movq_mf(uint64_t *mem)
 {
-    /* movq %mm0, (%rax) */
-    extern char movq_start, movq_end;
+	/* 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;
-    handle_exception(MF_VECTOR, advance_rip_and_note_exception);
-    asm volatile("fninit; fldcw %0" : : "m"(fcw));
-    asm volatile("fldz; fldz; fdivp"); /* generate exception */
+	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 */
 
-    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, 0);
+	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);
 }
 
 static void test_jmp_noncanonical(uint64_t *mem)
 {
 	extern char nc_jmp_start, nc_jmp_end;
+	handler old;
 
 	*mem = 0x1111111111111111ul;
 
 	exceptions = 0;
 	rip_advance = &nc_jmp_end - &nc_jmp_start;
-	handle_exception(GP_VECTOR, advance_rip_and_note_exception);
+	old = handle_exception(GP_VECTOR, advance_rip_and_note_exception);
 	asm volatile ("nc_jmp_start: jmp *%0; nc_jmp_end:" : : "m"(*mem));
 	report(exceptions == 1, "jump to non-canonical address");
-	handle_exception(GP_VECTOR, 0);
+	handle_exception(GP_VECTOR, old);
 }
 
 static void test_movabs(uint64_t *mem)
@@ -979,22 +982,23 @@ static void ss_bad_rpl(struct ex_regs *regs)
 
 static void test_sreg(volatile uint16_t *mem)
 {
-    u16 ss = read_ss();
+	u16 ss = read_ss();
+	handler old;
 
-    // check for null segment load
-    *mem = 0;
-    asm volatile("mov %0, %%ss" : : "m"(*mem));
-    report(read_ss() == 0, "mov null, %%ss");
+	// check for null segment load
+	*mem = 0;
+	asm volatile("mov %0, %%ss" : : "m"(*mem));
+	report(read_ss() == 0, "mov null, %%ss");
 
-    // check for exception when ss.rpl != cpl on null segment load
-    exceptions = 0;
-    handle_exception(GP_VECTOR, ss_bad_rpl);
-    *mem = 3;
-    asm volatile("mov %0, %%ss; ss_bad_rpl_cont:" : : "m"(*mem));
-    report(exceptions == 1 && read_ss() == 0,
-           "mov null, %%ss (with ss.rpl != cpl)");
-    handle_exception(GP_VECTOR, 0);
-    write_ss(ss);
+	// check for exception when ss.rpl != cpl on null segment load
+	exceptions = 0;
+	old = handle_exception(GP_VECTOR, ss_bad_rpl);
+	*mem = 3;
+	asm volatile("mov %0, %%ss; ss_bad_rpl_cont:" : : "m"(*mem));
+	report(exceptions == 1 && read_ss() == 0,
+	       "mov null, %%ss (with ss.rpl != cpl)");
+	handle_exception(GP_VECTOR, old);
+	write_ss(ss);
 }
 
 static uint64_t usr_gs_mov(void)
-- 
2.37.1.559.g78731f0fdb-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [kvm-unit-tests PATCH v3 2/7] x86: Dedup 32-bit vs. 64-bit ASM_TRY() by stealing kernel's __ASM_SEL()
  2022-08-08 16:47 [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups Sean Christopherson
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 1/7] x86: emulator.c: Save and restore exception handlers Sean Christopherson
@ 2022-08-08 16:47 ` Sean Christopherson
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 3/7] x86: Introduce ASM_TRY_FEP() to handle exceptions on forced emulation Sean Christopherson
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sean Christopherson @ 2022-08-08 16:47 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Michal Luczaj

Steal the kernel's __ASM_SEL() implementation and use it to consolidate
ASM_TRY().  The only difference between the 32-bit and 64-bit versions is
the size of the address stored in the table.

No functional change intended.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 lib/x86/desc.h | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/lib/x86/desc.h b/lib/x86/desc.h
index 2a285eb..10ba8cb 100644
--- a/lib/x86/desc.h
+++ b/lib/x86/desc.h
@@ -3,6 +3,18 @@
 
 #include <setjmp.h>
 
+#ifdef __ASSEMBLY__
+#define __ASM_FORM(x, ...)	x,## __VA_ARGS__
+#else
+#define __ASM_FORM(x, ...)	" " xstr(x,##__VA_ARGS__) " "
+#endif
+
+#ifndef __x86_64__
+#define __ASM_SEL(a,b)		__ASM_FORM(a)
+#else
+#define __ASM_SEL(a,b)		__ASM_FORM(b)
+#endif
+
 void setup_idt(void);
 void load_idt(void);
 void setup_alt_stack(void);
@@ -80,21 +92,12 @@ typedef struct  __attribute__((packed)) {
 	u16 iomap_base;
 } tss64_t;
 
-#ifdef __x86_64
-#define ASM_TRY(catch)			\
-	"movl $0, %%gs:4 \n\t"		\
-	".pushsection .data.ex \n\t"	\
-	".quad 1111f, " catch "\n\t"	\
-	".popsection \n\t"		\
+#define ASM_TRY(catch)						\
+	"movl $0, %%gs:4 \n\t"					\
+	".pushsection .data.ex \n\t"				\
+	__ASM_SEL(.long, .quad) " 1111f,  " catch "\n\t"	\
+	".popsection \n\t"					\
 	"1111:"
-#else
-#define ASM_TRY(catch)			\
-	"movl $0, %%gs:4 \n\t"		\
-	".pushsection .data.ex \n\t"	\
-	".long 1111f, " catch "\n\t"	\
-	".popsection \n\t"		\
-	"1111:"
-#endif
 
 /*
  * selector     32-bit                        64-bit
-- 
2.37.1.559.g78731f0fdb-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [kvm-unit-tests PATCH v3 3/7] x86: Introduce ASM_TRY_FEP() to handle exceptions on forced emulation
  2022-08-08 16:47 [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups Sean Christopherson
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 1/7] x86: emulator.c: Save and restore exception handlers Sean Christopherson
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 2/7] x86: Dedup 32-bit vs. 64-bit ASM_TRY() by stealing kernel's __ASM_SEL() Sean Christopherson
@ 2022-08-08 16:47 ` Sean Christopherson
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 4/7] x86: Add helper to detect if forced emulation prefix is available Sean Christopherson
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sean Christopherson @ 2022-08-08 16:47 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Michal Luczaj

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 --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
-- 
2.37.1.559.g78731f0fdb-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [kvm-unit-tests PATCH v3 4/7] x86: Add helper to detect if forced emulation prefix is available
  2022-08-08 16:47 [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups Sean Christopherson
                   ` (2 preceding siblings ...)
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 3/7] x86: Introduce ASM_TRY_FEP() to handle exceptions on forced emulation Sean Christopherson
@ 2022-08-08 16:47 ` Sean Christopherson
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 5/7] x86: emulator.c: Use ASM_TRY() for the UD_VECTOR cases Sean Christopherson
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sean Christopherson @ 2022-08-08 16:47 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Michal Luczaj

Add a helper to detect whether or not KVM's forced emulation prefix is
available.  Use the helper to replace equivalent functionality in the
emulator test.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 lib/x86/desc.h | 14 ++++++++++++++
 x86/emulator.c | 15 +--------------
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/lib/x86/desc.h b/lib/x86/desc.h
index 8f708fd..c023b93 100644
--- a/lib/x86/desc.h
+++ b/lib/x86/desc.h
@@ -106,6 +106,20 @@ typedef struct  __attribute__((packed)) {
 #define KVM_FEP "ud2; .byte 'k', 'v', 'm';"
 #define ASM_TRY_FEP(catch) __ASM_TRY(KVM_FEP, catch)
 
+static inline bool is_fep_available(void)
+{
+	/*
+	 * Use the non-FEP ASM_TRY() as KVM will inject a #UD on the prefix
+	 * itself if forced emulation is not available.
+	 */
+	asm goto(ASM_TRY("%l[fep_unavailable]")
+		 KVM_FEP "nop\n\t"
+		 ::: "memory" : fep_unavailable);
+	return true;
+fep_unavailable:
+	return false;
+}
+
 /*
  * selector     32-bit                        64-bit
  * 0x00         NULL descriptor               NULL descriptor
diff --git a/x86/emulator.c b/x86/emulator.c
index 6dc88f1..e1272a6 100644
--- a/x86/emulator.c
+++ b/x86/emulator.c
@@ -17,10 +17,6 @@
 
 static int exceptions;
 
-/* Forced emulation prefix, used to invoke the emulator unconditionally.  */
-#define KVM_FEP_LENGTH 5
-static int fep_available = 1;
-
 struct regs {
 	u64 rax, rbx, rcx, rdx;
 	u64 rsi, rdi, rsp, rbp;
@@ -1121,12 +1117,6 @@ static void test_illegal_movbe(void)
 	handle_exception(UD_VECTOR, 0);
 }
 
-static void record_no_fep(struct ex_regs *regs)
-{
-	fep_available = 0;
-	regs->rip += KVM_FEP_LENGTH;
-}
-
 int main(void)
 {
 	void *mem;
@@ -1136,9 +1126,6 @@ int main(void)
 	unsigned long t1, t2;
 
 	setup_vm();
-	handle_exception(UD_VECTOR, record_no_fep);
-	asm(KVM_FEP "nop");
-	handle_exception(UD_VECTOR, 0);
 
 	mem = alloc_vpages(2);
 	install_page((void *)read_cr3(), IORAM_BASE_PHYS, mem);
@@ -1190,7 +1177,7 @@ int main(void)
 	test_ltr(mem);
 	test_cmov(mem);
 
-	if (fep_available) {
+	if (is_fep_available()) {
 		test_mmx_movq_mf(mem);
 		test_movabs(mem);
 		test_smsw_reg(mem);
-- 
2.37.1.559.g78731f0fdb-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [kvm-unit-tests PATCH v3 5/7] x86: emulator.c: Use ASM_TRY() for the UD_VECTOR cases
  2022-08-08 16:47 [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups Sean Christopherson
                   ` (3 preceding siblings ...)
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 4/7] x86: Add helper to detect if forced emulation prefix is available Sean Christopherson
@ 2022-08-08 16:47 ` Sean Christopherson
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 6/7] x86: Test emulator's handling of LEA with /reg Sean Christopherson
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sean Christopherson @ 2022-08-08 16:47 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Michal Luczaj

From: Michal Luczaj <mhal@rbox.co>

For #UD handling use ASM_TRY() instead of handle_exception().

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Michal Luczaj <mhal@rbox.co>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 x86/emulator.c | 26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/x86/emulator.c b/x86/emulator.c
index e1272a6..cc20440 100644
--- a/x86/emulator.c
+++ b/x86/emulator.c
@@ -1094,27 +1094,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");
+
+	vector = exception_vector();
+	report(vector == UD_VECTOR,
+	       "Wanted #UD on MOVBE with /reg, got vector = %u", vector);
 }
 
 int main(void)
-- 
2.37.1.559.g78731f0fdb-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [kvm-unit-tests PATCH v3 6/7] x86: Test emulator's handling of LEA with /reg
  2022-08-08 16:47 [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups Sean Christopherson
                   ` (4 preceding siblings ...)
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 5/7] x86: emulator.c: Use ASM_TRY() for the UD_VECTOR cases Sean Christopherson
@ 2022-08-08 16:47 ` Sean Christopherson
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 7/7] x86/pmu: Run the "emulation" test iff forced emulation is available Sean Christopherson
  2022-08-10 19:06 ` [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups Paolo Bonzini
  7 siblings, 0 replies; 9+ messages in thread
From: Sean Christopherson @ 2022-08-08 16:47 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Michal Luczaj

From: Michal Luczaj <mhal@rbox.co>

LEA with a register-direct source operand is illegal. Verify that the
emulator raises #UD.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Michal Luczaj <mhal@rbox.co>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 x86/emulator.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/x86/emulator.c b/x86/emulator.c
index cc20440..7d97774 100644
--- a/x86/emulator.c
+++ b/x86/emulator.c
@@ -893,6 +893,20 @@ static void test_mov_dr(uint64_t *mem)
 		report(rax == DR6_ACTIVE_LOW, "mov_dr6");
 }
 
+static void test_illegal_lea(void)
+{
+	unsigned int vector;
+
+	asm volatile (ASM_TRY_FEP("1f")
+		      ".byte 0x8d; .byte 0xc0\n\t"
+		      "1:"
+		      : : : "memory", "eax");
+
+	vector = exception_vector();
+	report(vector == UD_VECTOR,
+	       "Wanted #UD on LEA with /reg, got vector = %u", vector);
+}
+
 static void test_push16(uint64_t *mem)
 {
 	uint64_t rsp1, rsp2;
@@ -1179,6 +1193,7 @@ int main(void)
 		test_smsw_reg(mem);
 		test_nop(mem);
 		test_mov_dr(mem);
+		test_illegal_lea();
 	} else {
 		report_skip("skipping register-only tests, "
 			    "use kvm.force_emulation_prefix=1 to enable");
-- 
2.37.1.559.g78731f0fdb-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [kvm-unit-tests PATCH v3 7/7] x86/pmu: Run the "emulation" test iff forced emulation is available
  2022-08-08 16:47 [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups Sean Christopherson
                   ` (5 preceding siblings ...)
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 6/7] x86: Test emulator's handling of LEA with /reg Sean Christopherson
@ 2022-08-08 16:47 ` Sean Christopherson
  2022-08-10 19:06 ` [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups Paolo Bonzini
  7 siblings, 0 replies; 9+ messages in thread
From: Sean Christopherson @ 2022-08-08 16:47 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Michal Luczaj

Run the PMU's emulation testcase if and only if forced emulation is
available, and do so without requiring the user to manually specify they
want to run the emulation testcase.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 x86/pmu.c         | 17 ++++++++---------
 x86/unittests.cfg |  7 -------
 2 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/x86/pmu.c b/x86/pmu.c
index 457c5b9..d59baf1 100644
--- a/x86/pmu.c
+++ b/x86/pmu.c
@@ -655,17 +655,16 @@ int main(int ac, char **av)
 
 	apic_write(APIC_LVTPC, PC_VECTOR);
 
-	if (ac > 1 && !strcmp(av[1], "emulation")) {
+	if (is_fep_available())
 		check_emulated_instr();
-	} else {
+
+	check_counters();
+
+	if (rdmsr(MSR_IA32_PERF_CAPABILITIES) & PMU_CAP_FW_WRITES) {
+		gp_counter_base = MSR_IA32_PMC0;
+		report_prefix_push("full-width writes");
 		check_counters();
-
-		if (rdmsr(MSR_IA32_PERF_CAPABILITIES) & PMU_CAP_FW_WRITES) {
-			gp_counter_base = MSR_IA32_PMC0;
-			report_prefix_push("full-width writes");
-			check_counters();
-			check_gp_counters_write_width();
-		}
+		check_gp_counters_write_width();
 	}
 
 	return report_summary();
diff --git a/x86/unittests.cfg b/x86/unittests.cfg
index 01d775e..ed65185 100644
--- a/x86/unittests.cfg
+++ b/x86/unittests.cfg
@@ -198,13 +198,6 @@ check = /sys/module/kvm/parameters/ignore_msrs=N
 check = /proc/sys/kernel/nmi_watchdog=0
 accel = kvm
 
-[pmu_emulation]
-file = pmu.flat
-arch = x86_64
-extra_params = -cpu max -append emulation
-check = /sys/module/kvm/parameters/force_emulation_prefix=Y
-accel = kvm
-
 [vmware_backdoors]
 file = vmware_backdoors.flat
 extra_params = -machine vmport=on -cpu max
-- 
2.37.1.559.g78731f0fdb-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups
  2022-08-08 16:47 [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups Sean Christopherson
                   ` (6 preceding siblings ...)
  2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 7/7] x86/pmu: Run the "emulation" test iff forced emulation is available Sean Christopherson
@ 2022-08-10 19:06 ` Paolo Bonzini
  7 siblings, 0 replies; 9+ messages in thread
From: Paolo Bonzini @ 2022-08-10 19:06 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: kvm, Michal Luczaj

On 8/8/22 18:47, Sean Christopherson wrote:
> Slightly reworked version of Michal's series clean up the FEP mess and add
> a testcase for illegal LEA.  Core ideas are all the same, just moved the
> common FEP functionality to desc.h to make it easier to use in other tests.
> 
> v3:
>   - Define __ASM_SEL/__ASM_FORM in desc.h to fix circular dependency.
>   - Move ASM_TRY_FEP() to desc.h
>   - Add is_fep_available() helper to simplify probing FEP.
>   - Use is_fep_available() in PMU test.
> 
> Michal Luczaj (4):
>    x86: emulator.c: Save and restore exception handlers
>    x86: Introduce ASM_TRY_FEP() to handle exceptions on forced emulation
>    x86: emulator.c: Use ASM_TRY() for the UD_VECTOR cases
>    x86: Test emulator's handling of LEA with /reg
> 
> Sean Christopherson (3):
>    x86: Dedup 32-bit vs. 64-bit ASM_TRY() by stealing kernel's
>      __ASM_SEL()
>    x86: Add helper to detect if forced emulation prefix is available
>    x86/pmu: Run the "emulation" test iff forced emulation is available
> 
>   lib/x86/desc.h    |  52 ++++++++++++++-----
>   x86/emulator.c    | 127 +++++++++++++++++++++++-----------------------
>   x86/pmu.c         |  18 +++----
>   x86/unittests.cfg |   7 ---
>   4 files changed, 110 insertions(+), 94 deletions(-)
> 
> 
> base-commit: a106b30d39425b7afbaa3bbd4aab16fd26d333e7

Queued, thanks.

Paolo


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-08-10 19:06 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-08 16:47 [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups Sean Christopherson
2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 1/7] x86: emulator.c: Save and restore exception handlers Sean Christopherson
2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 2/7] x86: Dedup 32-bit vs. 64-bit ASM_TRY() by stealing kernel's __ASM_SEL() Sean Christopherson
2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 3/7] x86: Introduce ASM_TRY_FEP() to handle exceptions on forced emulation Sean Christopherson
2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 4/7] x86: Add helper to detect if forced emulation prefix is available Sean Christopherson
2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 5/7] x86: emulator.c: Use ASM_TRY() for the UD_VECTOR cases Sean Christopherson
2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 6/7] x86: Test emulator's handling of LEA with /reg Sean Christopherson
2022-08-08 16:47 ` [kvm-unit-tests PATCH v3 7/7] x86/pmu: Run the "emulation" test iff forced emulation is available Sean Christopherson
2022-08-10 19:06 ` [kvm-unit-tests PATCH v3 0/7] x86: Illegal LEA test and FEP cleanups Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).