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@xxxxxxxxxxxxxxx> --- lib/x86/processor.h | 2 ++ x86/vmexit.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) 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 }, -- 1.8.3.1