[kvm-unit-tests RFC PATCH 14/17] x86 TDX: Add TDX specific test case

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

 



sub-test1:
Test APIC self IPI with vector < 16 trigger #VE.

sub-test2:
Test single step on simulation instructions work well with single step
emulation in #VE handler, we choose cpuid(0xb) and wrmsr(0x1a0) to test.
Please note not all cpuid trigger #VE, e.x. cpuid(0) will not.

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx>
Reviewed-by: Yu Zhang <yu.c.zhang@xxxxxxxxx>
---
 x86/Makefile.x86_64 |  1 +
 x86/intel_tdx.c     | 94 +++++++++++++++++++++++++++++++++++++++++++++
 x86/unittests.cfg   |  4 ++
 3 files changed, 99 insertions(+)
 create mode 100644 x86/intel_tdx.c

diff --git a/x86/Makefile.x86_64 b/x86/Makefile.x86_64
index a3cb75ae5868..de79212951a3 100644
--- a/x86/Makefile.x86_64
+++ b/x86/Makefile.x86_64
@@ -31,6 +31,7 @@ tests += $(TEST_DIR)/vmware_backdoors.$(exe)
 tests += $(TEST_DIR)/rdpru.$(exe)
 tests += $(TEST_DIR)/pks.$(exe)
 tests += $(TEST_DIR)/pmu_lbr.$(exe)
+tests += $(TEST_DIR)/intel_tdx.$(exe)
 
 ifeq ($(TARGET_EFI),y)
 tests += $(TEST_DIR)/amd_sev.$(exe)
diff --git a/x86/intel_tdx.c b/x86/intel_tdx.c
new file mode 100644
index 000000000000..e7e65fb32b89
--- /dev/null
+++ b/x86/intel_tdx.c
@@ -0,0 +1,94 @@
+#include "libcflat.h"
+#include "x86/processor.h"
+#include "x86/apic-defs.h"
+#include "x86/tdx.h"
+#include "msr.h"
+
+static volatile unsigned long db_addr[10], dr6[10];
+static volatile unsigned int n;
+
+static void test_selfipi_msr(void)
+{
+	unsigned char vector;
+	u64 i;
+
+	printf("start APIC_SELF_IPI MSR write test.\n");
+
+	for (i = 0; i < 16; i++) {
+		vector = wrmsr_checking(APIC_SELF_IPI, i);
+		report(vector == VE_VECTOR,
+		       "Expected #VE on WRSMR(%s, 0x%lx), got vector %d",
+		       "APIC_SELF_IPI", i, vector);
+	}
+
+	printf("end APIC_SELF_IPI MSR write test.\n");
+}
+
+static void handle_db(struct ex_regs *regs)
+{
+	db_addr[n] = regs->rip;
+	dr6[n] = read_dr6();
+
+	if (dr6[n] & 0x1)
+		regs->rflags |= (1 << 16);
+
+	if (++n >= 10) {
+		regs->rflags &= ~(1 << 8);
+		write_dr7(0x00000400);
+	}
+}
+
+static void test_single_step(void)
+{
+	unsigned long start;
+
+	handle_exception(DB_VECTOR, handle_db);
+
+	/*
+	 * cpuid(0xb) and wrmsr(0x1a0) trigger #VE and are then emulated.
+	 * Test #DB on these instructions as there is single step
+	 * simulation in #VE handler. This is complement to x86/debug.c
+	 * which test cpuid(0) and in(0x3fd) instruction. In fact,
+	 * cpuid(0) is emulated by seam module.
+	 */
+	n = 0;
+	write_dr6(0);
+	asm volatile(
+		"pushf\n\t"
+		"pop %%rax\n\t"
+		"or $(1<<8),%%rax\n\t"
+		"push %%rax\n\t"
+		"lea (%%rip),%0\n\t"
+		"popf\n\t"
+		"and $~(1<<8),%%rax\n\t"
+		"push %%rax\n\t"
+		"mov $0xb,%%rax\n\t"
+		"cpuid\n\t"
+		"movl $0x1a0,%%ecx\n\t"
+		"rdmsr\n\t"
+		"wrmsr\n\t"
+		"popf\n\t"
+		: "=r" (start) : : "rax", "ebx", "ecx", "edx");
+	report(n == 8 &&
+	       db_addr[0] == start + 1 + 6 && dr6[0] == 0xffff4ff0 &&
+	       db_addr[1] == start + 1 + 6 + 1 && dr6[1] == 0xffff4ff0 &&
+	       db_addr[2] == start + 1 + 6 + 1 + 7 && dr6[2] == 0xffff4ff0 &&
+	       db_addr[3] == start + 1 + 6 + 1 + 7 + 2 && dr6[3] == 0xffff4ff0 &&
+	       db_addr[4] == start + 1 + 6 + 1 + 7 + 2 + 5 && dr6[4] == 0xffff4ff0 &&
+	       db_addr[5] == start + 1 + 6 + 1 + 7 + 2 + 5 + 2 && dr6[5] == 0xffff4ff0 &&
+	       db_addr[6] == start + 1 + 6 + 1 + 7 + 2 + 5 + 2 + 2 && dr6[6] == 0xffff4ff0 &&
+	       db_addr[7] == start + 1 + 6 + 1 + 7 + 2 + 5 + 2 + 2 + 1 && dr6[6] == 0xffff4ff0,
+	       "single step emulated instructions");
+}
+
+int main(void)
+{
+	if (!is_tdx_guest()) {
+		printf("Not TDX environment!\n");
+		return report_summary();
+	}
+
+	test_selfipi_msr();
+	test_single_step();
+	return report_summary();
+}
diff --git a/x86/unittests.cfg b/x86/unittests.cfg
index 9a70ba3b4f2e..840e2054d54d 100644
--- a/x86/unittests.cfg
+++ b/x86/unittests.cfg
@@ -437,3 +437,7 @@ file = cet.flat
 arch = x86_64
 smp = 2
 extra_params = -enable-kvm -m 2048 -cpu host
+
+[intel_tdx]
+file = intel_tdx.flat
+arch = x86_64
-- 
2.25.1




[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