kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [kvm-unit-tests PATCH] x86: vmx: add regression test for posted interrupts
@ 2020-10-06 21:25 Oliver Upton
  2020-12-11 22:36 ` Jim Mattson
  2020-12-11 23:20 ` Paolo Bonzini
  0 siblings, 2 replies; 6+ messages in thread
From: Oliver Upton @ 2020-10-06 21:25 UTC (permalink / raw)
  To: kvm; +Cc: Jim Mattson, Paolo Bonzini, Sean Christopherson, Oliver Upton

If a guest blocks interrupts for the entirety of running in root mode
(RFLAGS.IF=0), a pending interrupt corresponding to the posted-interrupt
vector set in the VMCS should result in an interrupt posting to the vIRR
at VM-entry. However, on KVM this is not the case. The pending interrupt
is not recognized as the posted-interrupt vector and instead results in
an external interrupt VM-exit.

Add a regression test to exercise this issue.

Signed-off-by: Oliver Upton <oupton@google.com>
---
 lib/x86/asm/bitops.h |  8 +++++
 x86/vmx_tests.c      | 76 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+)

diff --git a/lib/x86/asm/bitops.h b/lib/x86/asm/bitops.h
index 13a25ec9853d..ce5743538f65 100644
--- a/lib/x86/asm/bitops.h
+++ b/lib/x86/asm/bitops.h
@@ -13,4 +13,12 @@
 
 #define HAVE_BUILTIN_FLS 1
 
+static inline void test_and_set_bit(long nr, unsigned long *addr)
+{
+	asm volatile("lock; bts %1, %0"
+		     : "+m" (*addr)
+		     : "Ir" (nr)
+		     : "memory");
+}
+
 #endif
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index d2084ae9e8ce..9ba9a5d452a2 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -10430,6 +10430,81 @@ static void atomic_switch_overflow_msrs_test(void)
 		test_skip("Test is only supported on KVM");
 }
 
+#define PI_VECTOR 0xe0
+#define PI_TEST_VECTOR 0x21
+
+static void enable_posted_interrupts(void)
+{
+	void *pi_desc = alloc_page();
+
+	vmcs_set_bits(PIN_CONTROLS, PIN_POST_INTR);
+	vmcs_set_bits(EXI_CONTROLS, EXI_INTA);
+	vmcs_write(PINV, PI_VECTOR);
+	vmcs_write(POSTED_INTR_DESC_ADDR, (u64)pi_desc);
+}
+
+static unsigned long *get_pi_desc(void)
+{
+	return (unsigned long *)vmcs_read(POSTED_INTR_DESC_ADDR);
+}
+
+static void post_interrupt(u8 vector, u32 dest)
+{
+	unsigned long *pi_desc = get_pi_desc();
+
+	test_and_set_bit(vector, pi_desc);
+	test_and_set_bit(256, pi_desc);
+	apic_icr_write(PI_VECTOR, dest);
+}
+
+static struct vmx_posted_interrupt_test_args {
+	bool isr_fired;
+} vmx_posted_interrupt_test_args;
+
+static void vmx_posted_interrupt_test_isr(isr_regs_t *regs)
+{
+	volatile struct vmx_posted_interrupt_test_args *args
+			= &vmx_posted_interrupt_test_args;
+
+	args->isr_fired = true;
+	eoi();
+}
+
+static void vmx_posted_interrupt_test_guest(void)
+{
+	handle_irq(PI_TEST_VECTOR, vmx_posted_interrupt_test_isr);
+	irq_enable();
+	vmcall();
+	asm volatile("nop");
+	vmcall();
+}
+
+static void vmx_posted_interrupt_test(void)
+{
+	volatile struct vmx_posted_interrupt_test_args *args
+			= &vmx_posted_interrupt_test_args;
+
+	if (!cpu_has_apicv()) {
+		report_skip(__func__);
+		return;
+	}
+
+	enable_vid();
+	enable_posted_interrupts();
+	test_set_guest(vmx_posted_interrupt_test_guest);
+
+	enter_guest();
+	skip_exit_vmcall();
+
+	irq_disable();
+	post_interrupt(PI_TEST_VECTOR, apic_id());
+	enter_guest();
+
+	skip_exit_vmcall();
+	TEST_ASSERT(args->isr_fired);
+	enter_guest();
+}
+
 #define TEST(name) { #name, .v2 = name }
 
 /* name/init/guest_main/exit_handler/syscall_handler/guest_regs */
@@ -10533,5 +10608,6 @@ struct vmx_test vmx_tests[] = {
 	TEST(rdtsc_vmexit_diff_test),
 	TEST(vmx_mtf_test),
 	TEST(vmx_mtf_pdpte_test),
+	TEST(vmx_posted_interrupt_test),
 	{ NULL, NULL, NULL, NULL, NULL, {0} },
 };
-- 
2.28.0.806.g8561365e88-goog


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

end of thread, other threads:[~2020-12-12  0:50 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-06 21:25 [kvm-unit-tests PATCH] x86: vmx: add regression test for posted interrupts Oliver Upton
2020-12-11 22:36 ` Jim Mattson
2020-12-11 23:20 ` Paolo Bonzini
2020-12-11 23:41   ` Oliver Upton
2020-12-12  0:17     ` Paolo Bonzini
     [not found]       ` <CAOQ_Qsij7LH8XK28XqgbNTJqct6Q7LZsniSB3xAvtbPm1uYL_Q@mail.gmail.com>
2020-12-12  0:34         ` 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).