diff mbox series

[kvm-unit-tests] x86: add Key Locker LOADIWKEY in vmexit test suite

Message ID 1625736951-14197-1-git-send-email-robert.hu@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series [kvm-unit-tests] x86: add Key Locker LOADIWKEY in vmexit test suite | expand

Commit Message

Robert Hoo July 8, 2021, 9:35 a.m. UTC
Key Locker feature is enumerated by CPUID.0x7:ECX[23].
Its loadiwkey instruction will cause VM-Exit.

Note: in current KVM implementation, host and guest can only exclusively
use this feature, i.e. host shall "clearcpuid=535" to expose this to guest.

Signed-off-by: Robert Hoo <robert.hu@linux.intel.com>
---
 lib/x86/processor.h |  2 ++
 x86/vmexit.c        | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+)
diff mbox series

Patch

diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index 173520f..4168682 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -154,6 +154,7 @@  static inline bool is_intel(void)
 #define	X86_FEATURE_MCE			(CPUID(0x1, 0, EDX, 7))
 #define	X86_FEATURE_APIC		(CPUID(0x1, 0, EDX, 9))
 #define	X86_FEATURE_CLFLUSH		(CPUID(0x1, 0, EDX, 19))
+#define	X86_FEATURE_FXSR		(CPUID(0x1, 0, EDX, 24))
 #define	X86_FEATURE_XMM			(CPUID(0x1, 0, EDX, 25))
 #define	X86_FEATURE_XMM2		(CPUID(0x1, 0, EDX, 26))
 #define	X86_FEATURE_TSC_ADJUST		(CPUID(0x7, 0, EBX, 1))
@@ -171,6 +172,7 @@  static inline bool is_intel(void)
 #define	X86_FEATURE_RDPID		(CPUID(0x7, 0, ECX, 22))
 #define	X86_FEATURE_SHSTK		(CPUID(0x7, 0, ECX, 7))
 #define	X86_FEATURE_IBT			(CPUID(0x7, 0, EDX, 20))
+#define	X86_FEATURE_KEYLOCKER		(CPUID(0x7, 0, ECX, 23))
 #define	X86_FEATURE_SPEC_CTRL		(CPUID(0x7, 0, EDX, 26))
 #define	X86_FEATURE_ARCH_CAPABILITIES	(CPUID(0x7, 0, EDX, 29))
 #define	X86_FEATURE_PKS			(CPUID(0x7, 0, ECX, 31))
diff --git a/x86/vmexit.c b/x86/vmexit.c
index 999babf..88e64da 100644
--- a/x86/vmexit.c
+++ b/x86/vmexit.c
@@ -459,6 +459,24 @@  static void wr_ibpb_msr(void)
 	wrmsr(MSR_IA32_PRED_CMD, 1);
 }
 
+#define LOADIWKEY	".byte 0xf3,0x0f,0x38,0xdc,0xd1"
+#define CR4_KEYLOCKER (1 << 19)
+#define CR4_OSFXSR	  (1 << 9)
+static int has_keylocker(void)
+{
+	return !!(this_cpu_has(X86_FEATURE_KEYLOCKER)) &&
+		   !!(this_cpu_has(X86_FEATURE_FXSR));
+}
+
+static void loadiwkey(void)
+{
+	ulong cr4 = read_cr4();
+	/* loadiwkey instruction requires CR4.KL and CR4.OSFXSR */
+	write_cr4(cr4 | CR4_KEYLOCKER | CR4_OSFXSR);
+	asm volatile(LOADIWKEY : : "a" (0x0));
+	write_cr4(cr4 & ~(CR4_KEYLOCKER | CR4_OSFXSR));
+}
+
 static struct test tests[] = {
 	{ cpuid_test, "cpuid", .parallel = 1,  },
 	{ vmcall, "vmcall", .parallel = 1, },
@@ -466,6 +484,7 @@  static struct test tests[] = {
 	{ mov_from_cr8, "mov_from_cr8", .parallel = 1, },
 	{ mov_to_cr8, "mov_to_cr8" , .parallel = 1, },
 #endif
+	{ loadiwkey, "loadiwkey", has_keylocker, .parallel = 1,},
 	{ inl_pmtimer, "inl_from_pmtimer", .parallel = 1, },
 	{ inl_nop_qemu, "inl_from_qemu", .parallel = 1 },
 	{ inl_nop_kernel, "inl_from_kernel", .parallel = 1 },