add vmx capability check
check some essential vmx capablility, will panic if processor doesn't support it. Tracked-On: #6584 Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
2b3c4b6d49
commit
db98f01b6e
|
@ -41,6 +41,42 @@ static struct cpu_capability {
|
|||
|
||||
static struct cpuinfo_x86 boot_cpu_data;
|
||||
|
||||
struct vmx_capability {
|
||||
uint32_t msr;
|
||||
uint32_t bits;
|
||||
};
|
||||
|
||||
/* SDM APPENDIX A:
|
||||
* Bits 31:0 indicate the allowed 0-settings of these controls. VM entry allows control X
|
||||
* to be 0 if bit X in the MSR is cleared to 0; if bit X in the MSR is set to 1,
|
||||
* VM entry fails if control X is 0.
|
||||
* Bits 63:32 indicate the allowed 1-settings of these controls. VM entry allows control X to be 1
|
||||
* if bit 32+X in the MSR is set to 1; if bit 32+X in the MSR is cleared to 0, VM entry fails if control X is 1.
|
||||
*/
|
||||
static struct vmx_capability vmx_caps[] = {
|
||||
{
|
||||
MSR_IA32_VMX_PINBASED_CTLS, VMX_PINBASED_CTLS_IRQ_EXIT
|
||||
},
|
||||
{
|
||||
MSR_IA32_VMX_PROCBASED_CTLS, VMX_PROCBASED_CTLS_TSC_OFF | VMX_PROCBASED_CTLS_TPR_SHADOW |
|
||||
VMX_PROCBASED_CTLS_IO_BITMAP | VMX_PROCBASED_CTLS_MSR_BITMAP |
|
||||
VMX_PROCBASED_CTLS_HLT | VMX_PROCBASED_CTLS_SECONDARY
|
||||
},
|
||||
{
|
||||
MSR_IA32_VMX_PROCBASED_CTLS2, VMX_PROCBASED_CTLS2_VAPIC | VMX_PROCBASED_CTLS2_EPT |
|
||||
VMX_PROCBASED_CTLS2_VPID | VMX_PROCBASED_CTLS2_RDTSCP |
|
||||
VMX_PROCBASED_CTLS2_UNRESTRICT | VMX_PROCBASED_CTLS2_XSVE_XRSTR |
|
||||
VMX_PROCBASED_CTLS2_PAUSE_LOOP
|
||||
},
|
||||
{
|
||||
MSR_IA32_VMX_EXIT_CTLS, VMX_EXIT_CTLS_ACK_IRQ | VMX_EXIT_CTLS_SAVE_PAT |
|
||||
VMX_EXIT_CTLS_LOAD_PAT | VMX_EXIT_CTLS_HOST_ADDR64
|
||||
},
|
||||
{
|
||||
MSR_IA32_VMX_ENTRY_CTLS, VMX_ENTRY_CTLS_LOAD_PAT | VMX_ENTRY_CTLS_IA32E_MODE
|
||||
}
|
||||
};
|
||||
|
||||
bool pcpu_has_cap(uint32_t bit)
|
||||
{
|
||||
uint32_t feat_idx = bit >> 5U;
|
||||
|
@ -457,6 +493,49 @@ static int32_t check_vmx_mmu_cap(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool is_vmx_cap_supported(uint32_t msr, uint32_t bits)
|
||||
{
|
||||
uint64_t vmx_msr;
|
||||
uint32_t vmx_msr_low, vmx_msr_high;
|
||||
|
||||
vmx_msr = msr_read(msr);
|
||||
vmx_msr_low = (uint32_t)vmx_msr;
|
||||
vmx_msr_high = (uint32_t)(vmx_msr >> 32U);
|
||||
/* Bits 31:0 indicate the allowed 0-settings
|
||||
* Bits 63:32 indicate the allowed 1-settings
|
||||
*/
|
||||
return (((vmx_msr_high & bits) == bits) && ((vmx_msr_low & bits) == 0U));
|
||||
}
|
||||
|
||||
static int32_t check_essential_vmx_caps(void)
|
||||
{
|
||||
int32_t ret = 0;
|
||||
uint32_t i;
|
||||
|
||||
if (check_vmx_mmu_cap() != 0) {
|
||||
ret = -ENODEV;
|
||||
} else if (!pcpu_has_vmx_unrestricted_guest_cap()) {
|
||||
printf("%s, unrestricted guest not supported\n", __func__);
|
||||
ret = -ENODEV;
|
||||
} else if (pcpu_vmx_set_32bit_addr_width()) {
|
||||
printf("%s, Only support Intel 64 architecture.\n", __func__);
|
||||
ret = -ENODEV;
|
||||
} else if (!is_valid_xsave_combination()) {
|
||||
printf("%s, check XSAVE combined Capability failed\n", __func__);
|
||||
ret = -ENODEV;
|
||||
} else {
|
||||
for (i = 0U; i < ARRAY_SIZE(vmx_caps); i++) {
|
||||
if (!is_vmx_cap_supported(vmx_caps[i].msr, vmx_caps[i].bits)) {
|
||||
printf("%s, check MSR[0x%x]:0x%lx bits:0x%x failed\n", __func__,
|
||||
vmx_caps[i].msr, msr_read(vmx_caps[i].msr), vmx_caps[i].bits);
|
||||
ret = -ENODEV;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* basic hardware capability check
|
||||
|
@ -515,9 +594,6 @@ int32_t detect_hardware_support(void)
|
|||
ret = -ENODEV;
|
||||
} else if (!is_fast_string_erms_supported_and_enabled()) {
|
||||
ret = -ENODEV;
|
||||
} else if (!pcpu_has_vmx_unrestricted_guest_cap()) {
|
||||
printf("%s, unrestricted guest not supported\n", __func__);
|
||||
ret = -ENODEV;
|
||||
} else if (!is_ept_supported()) {
|
||||
printf("%s, EPT not supported\n", __func__);
|
||||
ret = -ENODEV;
|
||||
|
@ -530,9 +606,6 @@ int32_t detect_hardware_support(void)
|
|||
} else if (is_vmx_disabled()) {
|
||||
printf("%s, VMX can not be enabled\n", __func__);
|
||||
ret = -ENODEV;
|
||||
} else if (pcpu_vmx_set_32bit_addr_width()) {
|
||||
printf("%s, Only support Intel 64 architecture.\n", __func__);
|
||||
ret = -ENODEV;
|
||||
} else if (!pcpu_has_cap(X86_FEATURE_X2APIC)) {
|
||||
printf("%s, x2APIC not supported\n", __func__);
|
||||
ret = -ENODEV;
|
||||
|
@ -545,11 +618,8 @@ int32_t detect_hardware_support(void)
|
|||
} else if (!pcpu_has_cap(X86_FEATURE_RDRAND)) {
|
||||
printf("%s, RDRAND is not supported\n", __func__);
|
||||
ret = -ENODEV;
|
||||
} else if (!is_valid_xsave_combination()) {
|
||||
printf("%s, check XSAVE combined Capability failed\n", __func__);
|
||||
ret = -ENODEV;
|
||||
} else {
|
||||
ret = check_vmx_mmu_cap();
|
||||
ret = check_essential_vmx_caps();
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue