mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-28 08:16:54 +00:00
hv: keylocker: Simulate CPUID of keylocker caps for guest VM
KeyLocker is a new security feature available in new Intel CPUs that protects data-encryption keys for the Advanced Encryption Standard (AES) algorithm. This patch emulates Keylocker CPUID leaf 19H to support Keylocker feature for guest VM. To make the hypervisor being able to manage the IWKey correctly, this patch doesn't expose hardware random IWKey capability (CPUID.0x19.ECX[1]) to guest VM. Tracked-On: #5695 Signed-off-by: Shuo A Liu <shuo.a.liu@intel.com> Acked-by: Eddie Dong <eddie.dong@Intel.com>
This commit is contained in:
parent
15c967ad34
commit
e9247dbca0
@ -42,6 +42,7 @@ static uint64_t startup_paddr = 0UL;
|
|||||||
static volatile uint64_t pcpu_active_bitmap = 0UL;
|
static volatile uint64_t pcpu_active_bitmap = 0UL;
|
||||||
|
|
||||||
static void init_pcpu_xsave(void);
|
static void init_pcpu_xsave(void);
|
||||||
|
static void init_keylocker(void);
|
||||||
static void set_current_pcpu_id(uint16_t pcpu_id);
|
static void set_current_pcpu_id(uint16_t pcpu_id);
|
||||||
static void print_hv_banner(void);
|
static void print_hv_banner(void);
|
||||||
static uint16_t get_pcpu_id_from_lapic_id(uint32_t lapic_id);
|
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_smep();
|
||||||
|
|
||||||
enable_smap();
|
enable_smap();
|
||||||
|
|
||||||
|
init_keylocker();
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t get_pcpu_id_from_lapic_id(uint32_t lapic_id)
|
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)
|
static void smpcall_write_msr_func(void *data)
|
||||||
{
|
{
|
||||||
|
@ -362,7 +362,7 @@ int32_t set_vcpuid_entries(struct acrn_vm *vm)
|
|||||||
|
|
||||||
for (i = 1U; i <= limit; i++) {
|
for (i = 1U; i <= limit; i++) {
|
||||||
/* cpuid 1/0xb is percpu related */
|
/* cpuid 1/0xb is percpu related */
|
||||||
if ((i == 1U) || (i == 0xbU) || (i == 0xdU)) {
|
if ((i == 1U) || (i == 0xbU) || (i == 0xdU) || (i == 0x19U)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,7 +426,7 @@ int32_t set_vcpuid_entries(struct acrn_vm *vm)
|
|||||||
|
|
||||||
static inline bool is_percpu_related(uint32_t leaf)
|
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)
|
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,
|
static void guest_cpuid_80000001h(const struct acrn_vcpu *vcpu,
|
||||||
uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
|
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);
|
guest_cpuid_0dh(vcpu, eax, ebx, ecx, edx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x19U:
|
||||||
|
guest_cpuid_19h(vcpu, eax, ebx, ecx, edx);
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x80000001U:
|
case 0x80000001U:
|
||||||
guest_cpuid_80000001h(vcpu, eax, ebx, ecx, edx);
|
guest_cpuid_80000001h(vcpu, eax, ebx, ecx, edx);
|
||||||
break;
|
break;
|
||||||
|
@ -78,6 +78,9 @@
|
|||||||
#define X86_FEATURE_SMAP ((FEAT_7_0_EBX << 5U) + 20U)
|
#define X86_FEATURE_SMAP ((FEAT_7_0_EBX << 5U) + 20U)
|
||||||
#define X86_FEATURE_CLFLUSHOPT ((FEAT_7_0_EBX << 5U) + 23U)
|
#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)*/
|
/* Intel-defined CPU features, CPUID level 0x00000007 (EDX)*/
|
||||||
#define X86_FEATURE_MDS_CLEAR ((FEAT_7_0_EDX << 5U) + 10U)
|
#define X86_FEATURE_MDS_CLEAR ((FEAT_7_0_EDX << 5U) + 10U)
|
||||||
#define X86_FEATURE_IBRS_IBPB ((FEAT_7_0_EDX << 5U) + 26U)
|
#define X86_FEATURE_IBRS_IBPB ((FEAT_7_0_EDX << 5U) + 26U)
|
||||||
|
@ -126,6 +126,14 @@
|
|||||||
#define CPUID_EAX_SGX1 (1U<<0U)
|
#define CPUID_EAX_SGX1 (1U<<0U)
|
||||||
/* CPUID.12H.EAX.SGX2 */
|
/* CPUID.12H.EAX.SGX2 */
|
||||||
#define CPUID_EAX_SGX2 (1U<<1U)
|
#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 */
|
/* CPUID.80000001H.EDX.XD_BIT_AVAILABLE */
|
||||||
#define CPUID_EDX_XD_BIT_AVIL (1U<<20U)
|
#define CPUID_EDX_XD_BIT_AVIL (1U<<20U)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user