diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index ab0d27a76..803726fb2 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -42,6 +42,7 @@ static uint64_t startup_paddr = 0UL; static volatile uint64_t pcpu_active_bitmap = 0UL; static void init_pcpu_xsave(void); +static void init_keylocker(void); static void set_current_pcpu_id(uint16_t pcpu_id); static void print_hv_banner(void); static uint16_t get_pcpu_id_from_lapic_id(uint32_t lapic_id); @@ -291,6 +292,8 @@ void init_pcpu_post(uint16_t pcpu_id) enable_smep(); enable_smap(); + + init_keylocker(); } static uint16_t get_pcpu_id_from_lapic_id(uint32_t lapic_id) @@ -543,6 +546,17 @@ static void init_pcpu_xsave(void) } } +static void init_keylocker(void) +{ + uint64_t val64; + + /* Enable host CR4.KL if keylocker feature is supported */ + if (pcpu_has_cap(X86_FEATURE_KEYLOCKER)) { + CPU_CR_READ(cr4, &val64); + val64 |= CR4_KL; + CPU_CR_WRITE(cr4, val64); + } +} static void smpcall_write_msr_func(void *data) { diff --git a/hypervisor/arch/x86/guest/vcpuid.c b/hypervisor/arch/x86/guest/vcpuid.c index 7b48ca6d2..0621aac78 100644 --- a/hypervisor/arch/x86/guest/vcpuid.c +++ b/hypervisor/arch/x86/guest/vcpuid.c @@ -362,7 +362,7 @@ int32_t set_vcpuid_entries(struct acrn_vm *vm) for (i = 1U; i <= limit; i++) { /* cpuid 1/0xb is percpu related */ - if ((i == 1U) || (i == 0xbU) || (i == 0xdU)) { + if ((i == 1U) || (i == 0xbU) || (i == 0xdU) || (i == 0x19U)) { continue; } @@ -426,7 +426,7 @@ int32_t set_vcpuid_entries(struct acrn_vm *vm) static inline bool is_percpu_related(uint32_t leaf) { - return ((leaf == 0x1U) || (leaf == 0xbU) || (leaf == 0xdU) || (leaf == 0x80000001U)); + return ((leaf == 0x1U) || (leaf == 0xbU) || (leaf == 0xdU) || (leaf == 0x19U) || (leaf == 0x80000001U)); } static void guest_cpuid_01h(struct acrn_vcpu *vcpu, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) @@ -581,6 +581,23 @@ static void guest_cpuid_0dh(__unused struct acrn_vcpu *vcpu, uint32_t *eax, uint } } +static void guest_cpuid_19h(struct acrn_vcpu *vcpu, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) +{ + if (pcpu_has_cap(X86_FEATURE_KEYLOCKER)) { + /* Host CR4.KL should be enabled at boot time */ + cpuid_subleaf(0x19U, 0U, eax, ebx, ecx, edx); + /* Guest CR4.KL determines KL_AES_ENABLED */ + *ebx &= ~(vcpu->arch.cr4_kl_enabled ? 0U : CPUID_EBX_KL_AES_EN); + /* Don't support nobackup and randomization parameter of LOADIWKEY */ + *ecx &= ~(CPUID_ECX_KL_NOBACKUP | CPUID_ECX_KL_RANDOM_KS); + } else { + *eax = 0U; + *ebx = 0U; + *ecx = 0U; + *edx = 0U; + } +} + static void guest_cpuid_80000001h(const struct acrn_vcpu *vcpu, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { @@ -660,6 +677,10 @@ void guest_cpuid(struct acrn_vcpu *vcpu, uint32_t *eax, uint32_t *ebx, uint32_t guest_cpuid_0dh(vcpu, eax, ebx, ecx, edx); break; + case 0x19U: + guest_cpuid_19h(vcpu, eax, ebx, ecx, edx); + break; + case 0x80000001U: guest_cpuid_80000001h(vcpu, eax, ebx, ecx, edx); break; diff --git a/hypervisor/include/arch/x86/cpufeatures.h b/hypervisor/include/arch/x86/cpufeatures.h index e865b00b1..2e9cc9238 100644 --- a/hypervisor/include/arch/x86/cpufeatures.h +++ b/hypervisor/include/arch/x86/cpufeatures.h @@ -78,6 +78,9 @@ #define X86_FEATURE_SMAP ((FEAT_7_0_EBX << 5U) + 20U) #define X86_FEATURE_CLFLUSHOPT ((FEAT_7_0_EBX << 5U) + 23U) +/* Intel-defined CPU features, CPUID level 0x00000007 (ECX)*/ +#define X86_FEATURE_KEYLOCKER ((FEAT_7_0_ECX << 5U) + 23U) + /* Intel-defined CPU features, CPUID level 0x00000007 (EDX)*/ #define X86_FEATURE_MDS_CLEAR ((FEAT_7_0_EDX << 5U) + 10U) #define X86_FEATURE_IBRS_IBPB ((FEAT_7_0_EDX << 5U) + 26U) diff --git a/hypervisor/include/arch/x86/cpuid.h b/hypervisor/include/arch/x86/cpuid.h index 25ebe7c82..1d2cea53a 100644 --- a/hypervisor/include/arch/x86/cpuid.h +++ b/hypervisor/include/arch/x86/cpuid.h @@ -126,6 +126,14 @@ #define CPUID_EAX_SGX1 (1U<<0U) /* CPUID.12H.EAX.SGX2 */ #define CPUID_EAX_SGX2 (1U<<1U) +/* CPUID.19H.EBX.KL_AES_ENABLED */ +#define CPUID_EBX_KL_AES_EN (1U<<0U) +/* CPUID.19H.EBX.KL_BACKUP_MSR */ +#define CPUID_EBX_KL_BACKUP_MSR (1U<<4U) +/* CPUID.19H.ECX.KL_NOBACKUP */ +#define CPUID_ECX_KL_NOBACKUP (1U<<0U) +/* CPUID.19H.ECX.KL_RANDOM_KS */ +#define CPUID_ECX_KL_RANDOM_KS (1U<<1U) /* CPUID.80000001H.EDX.XD_BIT_AVAILABLE */ #define CPUID_EDX_XD_BIT_AVIL (1U<<20U)