diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index 512ec916e..3c2805e0b 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -31,7 +31,7 @@ static uint64_t start_tsc __attribute__((__section__(".bss_noinit"))); static void init_percpu_lapic_id(void) { uint16_t i; - uint16_t pcpu_num = 0U; + uint16_t pcpu_num; uint32_t lapic_id_array[CONFIG_MAX_PCPU_NUM]; /* Save all lapic_id detected via parse_mdt in lapic_id_array */ @@ -68,8 +68,10 @@ static void cpu_set_current_state(uint16_t pcpu_id, enum pcpu_boot_state state) per_cpu(boot_state, pcpu_id) = state; } -void init_cpu_pre(uint16_t pcpu_id) +void init_cpu_pre(uint16_t pcpu_id_args) { + uint16_t pcpu_id = pcpu_id_args; + if (pcpu_id == BOOT_CPU_ID) { start_tsc = rdtsc(); @@ -190,14 +192,16 @@ void init_cpu_post(uint16_t pcpu_id) static uint16_t get_cpu_id_from_lapic_id(uint32_t lapic_id) { uint16_t i; + uint16_t pcpu_id = INVALID_CPU_ID; for (i = 0U; (i < phys_cpu_num) && (i < CONFIG_MAX_PCPU_NUM); i++) { if (per_cpu(lapic_id, i) == lapic_id) { - return i; + pcpu_id = i; + break; } } - return INVALID_CPU_ID; + return pcpu_id; } static void start_cpu(uint16_t pcpu_id) diff --git a/hypervisor/arch/x86/cpu_caps.c b/hypervisor/arch/x86/cpu_caps.c index eb5b6f320..b3f713bb0 100644 --- a/hypervisor/arch/x86/cpu_caps.c +++ b/hypervisor/arch/x86/cpu_caps.c @@ -53,17 +53,19 @@ bool cpu_has_cap(uint32_t bit) bool has_monitor_cap(void) { + bool ret = false; + if (cpu_has_cap(X86_FEATURE_MONITOR)) { /* don't use monitor for CPU (family: 0x6 model: 0x5c) * in hypervisor, but still expose it to the guests and * let them handle it correctly */ if ((boot_cpu_data.family != 0x6U) || (boot_cpu_data.model != 0x5cU)) { - return true; + ret = true; } } - return false; + return ret; } static inline bool is_fast_string_erms_supported_and_enabled(void) @@ -133,42 +135,36 @@ static void detect_apicv_cap(void) uint64_t msr_val; msr_val = msr_read(MSR_IA32_VMX_PROCBASED_CTLS); + /* must support TPR shadow */ if (is_ctrl_setting_allowed(msr_val, VMX_PROCBASED_CTLS_TPR_SHADOW)) { features |= VAPIC_FEATURE_TPR_SHADOW; - } else { - /* must support TPR shadow */ - return; - } - msr_val = msr_read(MSR_IA32_VMX_PROCBASED_CTLS2); - if (is_ctrl_setting_allowed(msr_val, VMX_PROCBASED_CTLS2_VAPIC)) { - features |= VAPIC_FEATURE_VIRT_ACCESS; - if (is_ctrl_setting_allowed(msr_val, VMX_PROCBASED_CTLS2_VAPIC_REGS)) { - features |= VAPIC_FEATURE_VIRT_REG; - } else { - /* platform may only support APICV access */ - cpu_caps.apicv_features = features; - return; - } - } else { + msr_val = msr_read(MSR_IA32_VMX_PROCBASED_CTLS2); /* must support APICV access */ - return; - } + if (is_ctrl_setting_allowed(msr_val, VMX_PROCBASED_CTLS2_VAPIC)) { + features |= VAPIC_FEATURE_VIRT_ACCESS; + if (is_ctrl_setting_allowed(msr_val, VMX_PROCBASED_CTLS2_VAPIC_REGS)) { + features |= VAPIC_FEATURE_VIRT_REG; - if (is_ctrl_setting_allowed(msr_val, VMX_PROCBASED_CTLS2_VX2APIC)) { - features |= VAPIC_FEATURE_VX2APIC_MODE; - } + if (is_ctrl_setting_allowed(msr_val, VMX_PROCBASED_CTLS2_VX2APIC)) { + features |= VAPIC_FEATURE_VX2APIC_MODE; + } - if (is_ctrl_setting_allowed(msr_val, VMX_PROCBASED_CTLS2_VIRQ)) { - features |= VAPIC_FEATURE_INTR_DELIVERY; + if (is_ctrl_setting_allowed(msr_val, VMX_PROCBASED_CTLS2_VIRQ)) { + features |= VAPIC_FEATURE_INTR_DELIVERY; - msr_val = msr_read(MSR_IA32_VMX_PINBASED_CTLS); - if (is_ctrl_setting_allowed(msr_val, - VMX_PINBASED_CTLS_POST_IRQ)) { - features |= VAPIC_FEATURE_POST_INTR; + msr_val = msr_read(MSR_IA32_VMX_PINBASED_CTLS); + if (is_ctrl_setting_allowed(msr_val, VMX_PINBASED_CTLS_POST_IRQ)) { + features |= VAPIC_FEATURE_POST_INTR; + } + } + cpu_caps.apicv_features = features; + } else { + /* platform may only support APICV access */ + cpu_caps.apicv_features = features; + } } } - cpu_caps.apicv_features = features; } static void detect_vmx_mmu_cap(void) @@ -360,93 +356,62 @@ int32_t detect_hardware_support(void) /* 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.phys_bits == 0U) || + ret = -ENODEV; + } else if ((boot_cpu_data.phys_bits == 0U) || (boot_cpu_data.virt_bits == 0U)) { - 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, can't detect Linear/Physical Address size\n", __func__); + ret = -ENODEV; + } else if (!cpu_has_cap(X86_FEATURE_TSC_DEADLINE)) { + /* lapic TSC deadline timer */ pr_fatal("%s, TSC deadline not supported\n", __func__); - return -ENODEV; - } - - /* Execute Disable */ - if (!cpu_has_cap(X86_FEATURE_NX)) { + ret = -ENODEV; + } else if (!cpu_has_cap(X86_FEATURE_NX)) { + /* Execute Disable */ pr_fatal("%s, NX not supported\n", __func__); - return -ENODEV; - } - - /* Supervisor-Mode Execution Prevention */ - if (!cpu_has_cap(X86_FEATURE_SMEP)) { + ret = -ENODEV; + } else if (!cpu_has_cap(X86_FEATURE_SMEP)) { + /* Supervisor-Mode Execution Prevention */ pr_fatal("%s, SMEP not supported\n", __func__); - return -ENODEV; - } - - /* Supervisor-Mode Access Prevention */ - if (!cpu_has_cap(X86_FEATURE_SMAP)) { + ret = -ENODEV; + } else if (!cpu_has_cap(X86_FEATURE_SMAP)) { + /* Supervisor-Mode Access Prevention */ pr_fatal("%s, SMAP not supported\n", __func__); - return -ENODEV; - } - - if (!cpu_has_cap(X86_FEATURE_MTRR)) { + ret = -ENODEV; + } else if (!cpu_has_cap(X86_FEATURE_MTRR)) { pr_fatal("%s, MTRR not supported\n", __func__); - return -ENODEV; - } - - if (!cpu_has_cap(X86_FEATURE_PAGE1GB)) { + ret = -ENODEV; + } else if (!cpu_has_cap(X86_FEATURE_PAGE1GB)) { pr_fatal("%s, not support 1GB page\n", __func__); - return -ENODEV; - } - - if (!cpu_has_cap(X86_FEATURE_VMX)) { + ret = -ENODEV; + } else if (!cpu_has_cap(X86_FEATURE_VMX)) { pr_fatal("%s, vmx not supported\n", __func__); - return -ENODEV; - } - - if (!is_fast_string_erms_supported_and_enabled()) { - return -ENODEV; - } - - if (!cpu_has_vmx_unrestricted_guest_cap()) { + ret = -ENODEV; + } else if (!is_fast_string_erms_supported_and_enabled()) { + ret = -ENODEV; + } else if (!cpu_has_vmx_unrestricted_guest_cap()) { pr_fatal("%s, unrestricted guest not supported\n", __func__); - return -ENODEV; - } - - if (!is_ept_supported()) { + ret = -ENODEV; + } else if (!is_ept_supported()) { pr_fatal("%s, EPT not supported\n", __func__); - return -ENODEV; - } - - if (!is_apicv_supported()) { + ret = -ENODEV; + } else if (!is_apicv_supported()) { pr_fatal("%s, APICV not supported\n", __func__); - return -ENODEV; - } - - if (boot_cpu_data.cpuid_level < 0x15U) { + ret = -ENODEV; + } else if (boot_cpu_data.cpuid_level < 0x15U) { pr_fatal("%s, required CPU feature not supported\n", __func__); - return -ENODEV; - } - - if (is_vmx_disabled()) { + ret = -ENODEV; + } else if (is_vmx_disabled()) { pr_fatal("%s, VMX can not be enabled\n", __func__); - return -ENODEV; - } - - if (phys_cpu_num > CONFIG_MAX_PCPU_NUM) { + ret = -ENODEV; + } else if (phys_cpu_num > CONFIG_MAX_PCPU_NUM) { pr_fatal("%s, pcpu number(%d) is out of range\n", __func__, phys_cpu_num); - return -ENODEV; + ret = -ENODEV; + } else { + ret = check_vmx_mmu_cap(); + if (ret == 0) { + pr_acrnlog("hardware support HV"); + } } - ret = check_vmx_mmu_cap(); - if (ret != 0) { - return ret; - } - - pr_acrnlog("hardware support HV"); - return 0; + return ret; } diff --git a/hypervisor/arch/x86/security.c b/hypervisor/arch/x86/security.c index 36a697e41..8b2a90929 100644 --- a/hypervisor/arch/x86/security.c +++ b/hypervisor/arch/x86/security.c @@ -51,6 +51,7 @@ int32_t get_ibrs_type(void) bool check_cpu_security_cap(void) { + bool ret = true; uint64_t x86_arch_capabilities; detect_ibrs(); @@ -59,20 +60,18 @@ bool check_cpu_security_cap(void) x86_arch_capabilities = msr_read(MSR_IA32_ARCH_CAPABILITIES); skip_l1dfl_vmentry = ((x86_arch_capabilities & IA32_ARCH_CAP_SKIP_L1DFL_VMENTRY) != 0UL); + + if ((!cpu_has_cap(X86_FEATURE_L1D_FLUSH)) && (!skip_l1dfl_vmentry)) { + ret = false; + } else if ((!cpu_has_cap(X86_FEATURE_IBRS_IBPB)) && + (!cpu_has_cap(X86_FEATURE_STIBP))) { + ret = false; + } } else { - return false; + ret = false; } - if ((!cpu_has_cap(X86_FEATURE_L1D_FLUSH)) && (!skip_l1dfl_vmentry)) { - return false; - } - - if ((!cpu_has_cap(X86_FEATURE_IBRS_IBPB)) && - (!cpu_has_cap(X86_FEATURE_STIBP))) { - return false; - } - - return true; + return ret; } void cpu_l1d_flush(void) diff --git a/hypervisor/include/arch/x86/cpu.h b/hypervisor/include/arch/x86/cpu.h index 86211e83a..f83a76e83 100644 --- a/hypervisor/include/arch/x86/cpu.h +++ b/hypervisor/include/arch/x86/cpu.h @@ -251,7 +251,7 @@ void cpu_do_idle(void); void cpu_dead(void); void trampoline_start16(void); void load_cpu_state_data(void); -void init_cpu_pre(uint16_t pcpu_id); +void init_cpu_pre(uint16_t pcpu_id_args); void init_cpu_post(uint16_t pcpu_id); void start_cpus(void); void stop_cpus(void);