hv: check the availability of guest CR4 features

Check hardware support for all features in CR4,
 and hide bits from guest by vcpuid if they're not supported
 for guests OS.

Tracked-On: #5586
Signed-off-by: Yonghua Huang <yonghua.huang@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Yonghua Huang 2020-12-15 17:32:46 +08:00 committed by wenlingz
parent 442fc30117
commit 643bbcfe34
4 changed files with 75 additions and 3 deletions

View File

@ -115,6 +115,8 @@ static void init_vcpuid_entry(uint32_t leaf, uint32_t subleaf,
switch (leaf) { switch (leaf) {
case 0x07U: case 0x07U:
if (subleaf == 0U) { if (subleaf == 0U) {
uint64_t cr4_reserved_mask = get_cr4_reserved_bits();
cpuid_subleaf(leaf, subleaf, &entry->eax, &entry->ebx, &entry->ecx, &entry->edx); cpuid_subleaf(leaf, subleaf, &entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
entry->ebx &= ~(CPUID_EBX_PQM | CPUID_EBX_PQE); entry->ebx &= ~(CPUID_EBX_PQM | CPUID_EBX_PQE);
@ -132,6 +134,34 @@ static void init_vcpuid_entry(uint32_t leaf, uint32_t subleaf,
/* mask CET shadow stack and indirect branch tracking */ /* mask CET shadow stack and indirect branch tracking */
entry->ecx &= ~CPUID_ECX_CET_SS; entry->ecx &= ~CPUID_ECX_CET_SS;
entry->edx &= ~CPUID_EDX_CET_IBT; entry->edx &= ~CPUID_EDX_CET_IBT;
if ((cr4_reserved_mask & CR4_FSGSBASE) != 0UL) {
entry->ebx &= ~CPUID_EBX_FSGSBASE;
}
if ((cr4_reserved_mask & CR4_SMEP) != 0UL) {
entry->ebx &= ~CPUID_EBX_SMEP;
}
if ((cr4_reserved_mask & CR4_SMAP) != 0UL) {
entry->ebx &= ~CPUID_EBX_SMAP;
}
if ((cr4_reserved_mask & CR4_UMIP) != 0UL) {
entry->ecx &= ~CPUID_ECX_UMIP;
}
if ((cr4_reserved_mask & CR4_PKE) != 0UL) {
entry->ecx &= ~CPUID_ECX_PKE;
}
if ((cr4_reserved_mask & CR4_LA57) != 0UL) {
entry->ecx &= ~CPUID_ECX_LA57;
}
if ((cr4_reserved_mask & CR4_PKS) != 0UL) {
entry->ecx &= ~CPUID_ECX_PKS;
}
} else { } else {
entry->eax = 0U; entry->eax = 0U;
entry->ebx = 0U; entry->ebx = 0U;
@ -403,6 +433,7 @@ static void guest_cpuid_01h(struct acrn_vcpu *vcpu, uint32_t *eax, uint32_t *ebx
{ {
uint32_t apicid = vlapic_get_apicid(vcpu_vlapic(vcpu)); uint32_t apicid = vlapic_get_apicid(vcpu_vlapic(vcpu));
uint64_t guest_ia32_misc_enable = vcpu_get_guest_msr(vcpu, MSR_IA32_MISC_ENABLE); uint64_t guest_ia32_misc_enable = vcpu_get_guest_msr(vcpu, MSR_IA32_MISC_ENABLE);
uint64_t cr4_reserved_mask = get_cr4_reserved_bits();
cpuid_subleaf(0x1U, 0x0U, eax, ebx, ecx, edx); cpuid_subleaf(0x1U, 0x0U, eax, ebx, ecx, edx);
/* Patching initial APIC ID */ /* Patching initial APIC ID */
@ -431,7 +462,8 @@ static void guest_cpuid_01h(struct acrn_vcpu *vcpu, uint32_t *eax, uint32_t *ebx
/* set Hypervisor Present Bit */ /* set Hypervisor Present Bit */
*ecx |= CPUID_ECX_HV; *ecx |= CPUID_ECX_HV;
if ((get_cr4_reserved_bits() & CR4_PCIDE) != 0UL) {
if ((cr4_reserved_mask & CR4_PCIDE) != 0UL) {
*ecx &= ~CPUID_ECX_PCID; *ecx &= ~CPUID_ECX_PCID;
} }
@ -450,6 +482,30 @@ static void guest_cpuid_01h(struct acrn_vcpu *vcpu, uint32_t *eax, uint32_t *ebx
} }
} }
if ((cr4_reserved_mask & CR4_VME) != 0UL) {
*edx &= ~CPUID_EDX_VME;
}
if ((cr4_reserved_mask & CR4_DE) != 0UL) {
*edx &= ~CPUID_EDX_DE;
}
if ((cr4_reserved_mask & CR4_PSE) != 0UL) {
*edx &= ~CPUID_EDX_PSE;
}
if ((cr4_reserved_mask & CR4_PAE) != 0UL) {
*edx &= ~CPUID_EDX_PAE;
}
if ((cr4_reserved_mask & CR4_PGE) != 0UL) {
*edx &= ~CPUID_EDX_PGE;
}
if ((cr4_reserved_mask & CR4_OSFXSR) != 0UL) {
*edx &= ~CPUID_EDX_FXSR;
}
/* mask Debug Store feature */ /* mask Debug Store feature */
*edx &= ~CPUID_EDX_DTES; *edx &= ~CPUID_EDX_DTES;
*edx &= ~CPUID_EDX_MCE; *edx &= ~CPUID_EDX_MCE;

View File

@ -51,10 +51,10 @@
#define CR4_PASSTHRU_BITS (CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | \ #define CR4_PASSTHRU_BITS (CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | \
CR4_PGE | CR4_PCE | CR4_OSFXSR | CR4_PCIDE | \ CR4_PGE | CR4_PCE | CR4_OSFXSR | CR4_PCIDE | \
CR4_OSXSAVE | CR4_FSGSBASE | CR4_OSXMMEXCPT | \ CR4_OSXSAVE | CR4_FSGSBASE | CR4_OSXMMEXCPT | \
CR4_UMIP) CR4_UMIP | CR4_LA57)
static uint64_t cr4_passthru_mask = CR4_PASSTHRU_BITS; /* bound to flexible bits */ static uint64_t cr4_passthru_mask = CR4_PASSTHRU_BITS; /* bound to flexible bits */
#define CR4_TRAP_AND_PASSTHRU_BITS (CR4_PSE | CR4_PAE | CR4_SMEP | CR4_SMAP | CR4_PKE) #define CR4_TRAP_AND_PASSTHRU_BITS (CR4_PSE | CR4_PAE | CR4_SMEP | CR4_SMAP | CR4_PKE | CR4_PKS)
static uint64_t cr4_trap_and_passthru_mask = CR4_TRAP_AND_PASSTHRU_BITS; /* bound to flexible bits */ static uint64_t cr4_trap_and_passthru_mask = CR4_TRAP_AND_PASSTHRU_BITS; /* bound to flexible bits */
#define CR4_TRAP_AND_EMULATE_BITS 0UL /* software emulated bits even if host is fixed */ #define CR4_TRAP_AND_EMULATE_BITS 0UL /* software emulated bits even if host is fixed */

View File

@ -75,6 +75,7 @@
#define CR4_OSXMMEXCPT (1UL<<10U) #define CR4_OSXMMEXCPT (1UL<<10U)
/* OS support for unmasked SIMD floating point exceptions */ /* OS support for unmasked SIMD floating point exceptions */
#define CR4_UMIP (1UL<<11U) /* User-Mode Inst prevention */ #define CR4_UMIP (1UL<<11U) /* User-Mode Inst prevention */
#define CR4_LA57 (1UL<<12U) /* 57-bit linear address */
#define CR4_VMXE (1UL<<13U) /* VMX enable */ #define CR4_VMXE (1UL<<13U) /* VMX enable */
#define CR4_SMXE (1UL<<14U) /* SMX enable */ #define CR4_SMXE (1UL<<14U) /* SMX enable */
#define CR4_FSGSBASE (1UL<<16U) /* RD(FS|GS|FS)BASE inst */ #define CR4_FSGSBASE (1UL<<16U) /* RD(FS|GS|FS)BASE inst */
@ -85,6 +86,7 @@
#define CR4_SMAP (1UL<<21U) #define CR4_SMAP (1UL<<21U)
#define CR4_PKE (1UL<<22U) /* Protect-key-enable */ #define CR4_PKE (1UL<<22U) /* Protect-key-enable */
#define CR4_CET (1UL<<23U) /* Control-flow Enforcement Technology enable */ #define CR4_CET (1UL<<23U) /* Control-flow Enforcement Technology enable */
#define CR4_PKS (1UL<<24U) /* Enable protection keys for supervisor-mode pages */
/* XCR0_SSE */ /* XCR0_SSE */
#define XCR0_SSE (1UL<<1U) #define XCR0_SSE (1UL<<1U)

View File

@ -72,16 +72,30 @@
#define CPUID_EDX_TM1 (1U<<29U) #define CPUID_EDX_TM1 (1U<<29U)
#define CPUID_EDX_IA64 (1U<<30U) #define CPUID_EDX_IA64 (1U<<30U)
#define CPUID_EDX_PBE (1U<<31U) #define CPUID_EDX_PBE (1U<<31U)
/* CPUID.07H:EBX.FSGSBASE*/
#define CPUID_EBX_FSGSBASE (1U<<0U)
/* CPUID.07H:EBX.TSC_ADJUST*/ /* CPUID.07H:EBX.TSC_ADJUST*/
#define CPUID_EBX_TSC_ADJ (1U<<1U) #define CPUID_EBX_TSC_ADJ (1U<<1U)
/* CPUID.07H:EBX.SGX */ /* CPUID.07H:EBX.SGX */
#define CPUID_EBX_SGX (1U<<2U) #define CPUID_EBX_SGX (1U<<2U)
/* CPUID.07H:EBX.SMEP*/
#define CPUID_EBX_SMEP (1U<<7U)
/* CPUID.07H:EBX.MPX */ /* CPUID.07H:EBX.MPX */
#define CPUID_EBX_MPX (1U<<14U) #define CPUID_EBX_MPX (1U<<14U)
/* CPUID.07H:EBX.SMAP*/
#define CPUID_EBX_SMAP (1U<<20U)
/* CPUID.07H:ECX.UMIP */
#define CPUID_ECX_UMIP (1U<<2U)
/* CPUID.07H:ECX.PKE */
#define CPUID_ECX_PKE (1U<<3U)
/* CPUID.07H:ECX.CET_SS */ /* CPUID.07H:ECX.CET_SS */
#define CPUID_ECX_CET_SS (1U<<7U) #define CPUID_ECX_CET_SS (1U<<7U)
/* CPUID.07H:ECX.LA57 */
#define CPUID_ECX_LA57 (1U<<16U)
/* CPUID.07H:ECX.SGX_LC*/ /* CPUID.07H:ECX.SGX_LC*/
#define CPUID_ECX_SGX_LC (1U<<30U) #define CPUID_ECX_SGX_LC (1U<<30U)
/* CPUID.07H:ECX.PKS*/
#define CPUID_ECX_PKS (1U<<31U)
/* CPUID.07H:EDX.CET_IBT */ /* CPUID.07H:EDX.CET_IBT */
#define CPUID_EDX_CET_IBT (1U<<20U) #define CPUID_EDX_CET_IBT (1U<<20U)
/* CPUID.07H:EDX.IBRS_IBPB*/ /* CPUID.07H:EDX.IBRS_IBPB*/