mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-22 01:07:57 +00:00
hv: add hardware_detect_support to detect which hardware we support
Now just add some basic feature/capability detect (not all). Vapic didn't add here for if we must support vapic then the code which for vapic not supported must remove, like mmio apic r/w. Signed-off-by: Li, Fei1 <fei1.li@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
@@ -126,7 +126,6 @@ static uint64_t get_address_mask(uint8_t limit)
|
||||
static void get_cpu_capabilities(void)
|
||||
{
|
||||
uint32_t eax, unused;
|
||||
uint32_t max_extended_function_idx;
|
||||
uint32_t family, model;
|
||||
|
||||
cpuid(CPUID_FEATURES, &eax, &unused,
|
||||
@@ -149,28 +148,28 @@ static void get_cpu_capabilities(void)
|
||||
&boot_cpu_data.cpuid_leaves[FEAT_7_0_EDX]);
|
||||
|
||||
cpuid(CPUID_MAX_EXTENDED_FUNCTION,
|
||||
&max_extended_function_idx,
|
||||
&boot_cpu_data.extended_cpuid_level,
|
||||
&unused, &unused, &unused);
|
||||
boot_cpu_data.cpuid_leaves[FEAT_8000_0000_EAX] =
|
||||
max_extended_function_idx;
|
||||
|
||||
if (max_extended_function_idx < CPUID_EXTEND_ADDRESS_SIZE) {
|
||||
panic("CPU w/o CPUID.80000008H is not supported");
|
||||
if (boot_cpu_data.extended_cpuid_level >= CPUID_EXTEND_FUNCTION_1)
|
||||
cpuid(CPUID_EXTEND_FUNCTION_1, &unused, &unused,
|
||||
&boot_cpu_data.cpuid_leaves[FEAT_8000_0001_ECX],
|
||||
&boot_cpu_data.cpuid_leaves[FEAT_8000_0001_EDX]);
|
||||
|
||||
if (boot_cpu_data.extended_cpuid_level >= CPUID_EXTEND_ADDRESS_SIZE) {
|
||||
cpuid(CPUID_EXTEND_ADDRESS_SIZE, &eax,
|
||||
&boot_cpu_data.cpuid_leaves[FEAT_8000_0008_EBX],
|
||||
&unused, &unused);
|
||||
|
||||
/* EAX bits 07-00: #Physical Address Bits
|
||||
* bits 15-08: #Linear Address Bits
|
||||
*/
|
||||
boot_cpu_data.x86_virt_bits = (eax >> 8) & 0xff;
|
||||
boot_cpu_data.x86_phys_bits = eax & 0xff;
|
||||
boot_cpu_data.physical_address_mask =
|
||||
get_address_mask(boot_cpu_data.x86_phys_bits);
|
||||
}
|
||||
|
||||
cpuid(CPUID_EXTEND_FUNCTION_1, &unused, &unused,
|
||||
&boot_cpu_data.cpuid_leaves[FEAT_8000_0001_ECX],
|
||||
&boot_cpu_data.cpuid_leaves[FEAT_8000_0001_EDX]);
|
||||
|
||||
cpuid(CPUID_EXTEND_ADDRESS_SIZE,
|
||||
&eax, &unused, &unused, &unused);
|
||||
boot_cpu_data.cpuid_leaves[FEAT_8000_0008_EAX] = eax;
|
||||
/* EAX bits 07-00: #Physical Address Bits
|
||||
* bits 15-08: #Linear Address Bits
|
||||
*/
|
||||
boot_cpu_data.physical_address_mask =
|
||||
get_address_mask(eax & 0xff);
|
||||
|
||||
/* For speculation defence.
|
||||
* The default way is to set IBRS at vmexit and then do IBPB at vcpu
|
||||
* context switch(ibrs_type == IBRS_RAW).
|
||||
@@ -195,6 +194,64 @@ static void get_cpu_capabilities(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* basic hardware capability check
|
||||
* we should supplement which feature/capability we must support
|
||||
* here later.
|
||||
*/
|
||||
static int hardware_detect_support(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Long Mode (x86-64, 64-bit support) */
|
||||
if (!cpu_has_cap(X86_FEATURE_LM)) {
|
||||
pr_fatal("%s, LM not supported\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
if ((boot_cpu_data.x86_phys_bits == 0) ||
|
||||
(boot_cpu_data.x86_virt_bits == 0)) {
|
||||
pr_fatal("%s, can't detect Linear/Physical Address size\n",
|
||||
__func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* lapic TSC deadline timer */
|
||||
if (!cpu_has_cap(X86_FEATURE_TSC_DEADLINE)) {
|
||||
pr_fatal("%s, TSC deadline not supported\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Execute Disable */
|
||||
if (!cpu_has_cap(X86_FEATURE_NX)) {
|
||||
pr_fatal("%s, NX not supported\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Supervisor-Mode Execution Prevention */
|
||||
if (!cpu_has_cap(X86_FEATURE_SMEP)) {
|
||||
pr_fatal("%s, SMEP not supported\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Supervisor-Mode Access Prevention */
|
||||
if (!cpu_has_cap(X86_FEATURE_SMAP)) {
|
||||
pr_fatal("%s, SMAP not supported\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!cpu_has_cap(X86_FEATURE_VMX)) {
|
||||
pr_fatal("%s, vmx not supported\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = check_vmx_mmu_cap();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
printf("hardware support HV\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void alloc_phy_cpu_data(int pcpu_num)
|
||||
{
|
||||
phy_cpu_num = pcpu_num;
|
||||
@@ -458,6 +515,11 @@ void bsp_boot_init(void)
|
||||
|
||||
pr_dbg("Core %d is up", CPU_BOOT_ID);
|
||||
|
||||
if (hardware_detect_support() != 0) {
|
||||
pr_fatal("hardware not support!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Warn for security feature not ready */
|
||||
if (!cpu_has_cap(X86_FEATURE_IBRS_IBPB) &&
|
||||
!cpu_has_cap(X86_FEATURE_STIBP)) {
|
||||
@@ -492,7 +554,10 @@ void bsp_boot_init(void)
|
||||
|
||||
ASSERT(get_cpu_id() == CPU_BOOT_ID, "");
|
||||
|
||||
init_iommu();
|
||||
if (init_iommu() != 0) {
|
||||
pr_fatal("%s, init iommu failed\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
console_setup_timer();
|
||||
|
||||
|
@@ -94,7 +94,7 @@ static inline bool cpu_has_vmx_vpid_cap(uint32_t bit_mask)
|
||||
return !!(vmx_caps.vpid & bit_mask);
|
||||
}
|
||||
|
||||
static void check_mmu_capability(void)
|
||||
int check_vmx_mmu_cap(void)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
@@ -103,8 +103,17 @@ static void check_mmu_capability(void)
|
||||
vmx_caps.ept = (uint32_t) val;
|
||||
vmx_caps.vpid = (uint32_t) (val >> 32);
|
||||
|
||||
if (!cpu_has_vmx_ept_cap(VMX_EPT_INVEPT))
|
||||
panic("invept must be supported");
|
||||
if (!cpu_has_vmx_ept_cap(VMX_EPT_INVEPT)) {
|
||||
pr_fatal("%s, invept not supported\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!cpu_has_vmx_vpid_cap(VMX_VPID_INVVPID)) {
|
||||
pr_fatal("%s, invvpid not supported\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void invept(struct vcpu *vcpu)
|
||||
@@ -495,8 +504,6 @@ void init_paging(void)
|
||||
|
||||
pr_dbg("HV MMU Initialization");
|
||||
|
||||
check_mmu_capability();
|
||||
|
||||
/* Allocate memory for Hypervisor PML4 table */
|
||||
mmu_pml4_addr = alloc_paging_struct();
|
||||
|
||||
|
Reference in New Issue
Block a user