[PATCH kvm-unit-tests] x86: add SMM tests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add a generic speed test for SMIs and a testcase for
https://github.com/tianocore/edk2/issues/91.

Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 x86/Makefile.common |  1 +
 x86/smm_eventinj.c  | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 x86/unittests.cfg   |  4 +++
 x86/vmexit.c        |  6 ++++
 4 files changed, 94 insertions(+)
 create mode 100644 x86/smm_eventinj.c

diff --git a/x86/Makefile.common b/x86/Makefile.common
index 55e6cde..a04f14a 100644
--- a/x86/Makefile.common
+++ b/x86/Makefile.common
@@ -45,6 +45,7 @@ tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
                $(TEST_DIR)/tsc_adjust.flat $(TEST_DIR)/asyncpf.flat \
                $(TEST_DIR)/init.flat $(TEST_DIR)/smap.flat \
                $(TEST_DIR)/hyperv_synic.flat $(TEST_DIR)/hyperv_stimer.flat \
+               $(TEST_DIR)/smm_eventinj.flat
 
 ifdef API
 tests-common += api/api-sample
diff --git a/x86/smm_eventinj.c b/x86/smm_eventinj.c
new file mode 100644
index 0000000..1029289
--- /dev/null
+++ b/x86/smm_eventinj.c
@@ -0,0 +1,83 @@
+#include "libcflat.h"
+#include "smp.h"
+#include "processor.h"
+#include "x86/desc.h"
+#include "x86/apic.h"
+#include "x86/io.h"
+
+/* Provoke race between interrupt injection and SMM entry, causing a
+ * failed vmentry because IF=0 but VM_ENTRY_INTR_INFO_FIELD[31]=1.
+ */
+
+#define MY_IRQ_PIN 0x0e
+#define MY_IRQ_VEC 0x21
+
+static volatile int stopped;
+
+static void set_irq_line(unsigned line, int val)
+{
+	outb(val, 0x2000 + line);
+}
+
+static void set_ioapic_redir(unsigned line, unsigned vec)
+{
+	/* Edge triggered, CPU 0 */
+	ioapic_redir_entry_t e = {
+		.vector = vec,
+	};
+
+	ioapic_write_redir(line, e);
+}
+
+static void ipi(void *x)
+{
+	while (!stopped) {
+		int i = 0;
+		for (i = 0; i < 1000000; i++) asm("pause");
+
+		set_irq_line(MY_IRQ_PIN, 1);
+		apic_icr_write(APIC_DM_SMI|APIC_INT_ASSERT, 0);
+		set_irq_line(MY_IRQ_PIN, 0);
+	}
+}
+
+extern void dummy(void);
+asm("dummy: \n"
+    "call eoi\n"
+#ifndef __x86_64__
+    "iret"
+#else
+    "iretq"
+#endif
+   );
+
+int main(int ac, char **av)
+{
+	int i;
+
+	smp_init();
+        mask_pic_interrupts();
+
+	set_ioapic_redir(MY_IRQ_PIN, MY_IRQ_VEC);
+	set_idt_entry(MY_IRQ_VEC, dummy, 0);
+	if (cpu_count() < 2) {
+		printf("SMP needed for this test\n");
+		exit(1);
+	}
+
+	/* Because we use the APIC to inject SMIs, ensure SeaBIOS doesn't find
+	 * a valid "SMM command" in port 0xb2.  If it does, it peeks at the
+	 * registers to get the other parameters, and who knows what happens
+	 * then.
+	 */
+	outb(42, 0xb2);
+
+	printf("starting IPI thread\n");
+	on_cpu_async(1, ipi, 0);
+	printf("starting HLT loop\n");
+	asm("sti");
+	for (i = 0; i < 150; i++)
+		asm("hlt");
+	stopped = 1;
+	return 0;
+}
diff --git a/x86/unittests.cfg b/x86/unittests.cfg
index 61a4d24..6ba11fb 100644
--- a/x86/unittests.cfg
+++ b/x86/unittests.cfg
@@ -188,6 +188,10 @@ arch = x86_64
 file = debug.flat
 arch = x86_64
 
+[smm_eventinj]
+file = smm_eventinj.flat
+smp = 2
+
 [hyperv_synic]
 file = hyperv_synic.flat
 smp = 2
diff --git a/x86/vmexit.c b/x86/vmexit.c
index 9e04975..f21d054 100644
--- a/x86/vmexit.c
+++ b/x86/vmexit.c
@@ -134,6 +134,11 @@ static void wr_tsc_adjust_msr(void)
 	wrmsr(MSR_TSC_ADJUST, 0x0);
 }
 
+static void smi_outb(void)
+{
+	outb(42, 0xb2);
+}
+
 static struct pci_test {
 	unsigned iobar;
 	unsigned ioport;
@@ -287,6 +292,7 @@ static struct test tests[] = {
 	{ ple_round_robin, "ple-round-robin", .parallel = 1 },
 	{ wr_tsc_adjust_msr, "wr_tsc_adjust_msr", .parallel = 1 },
 	{ rd_tsc_adjust_msr, "rd_tsc_adjust_msr", .parallel = 1 },
+	{ smi_outb, "smi_outb", .parallel = 0 },
 	{ NULL, "pci-mem", .parallel = 0, .next = pci_mem_next },
 	{ NULL, "pci-io", .parallel = 0, .next = pci_io_next },
 };
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux