From e22217fd8f8fb40307468ec3afec03dea18c1a3d Mon Sep 17 00:00:00 2001 From: Jason Chen CJ Date: Mon, 17 Dec 2018 16:51:25 +0800 Subject: [PATCH] refine apicv capability check deinfe rule like below: - must support TPR shadow and apicv access - based on above, check apicv register support - based on above, check virtual interrupt delivery and post interrupt support Changes to be committed: modified: arch/x86/cpu_caps.c Tracked-On: #1842 Signed-off-by: Jason Chen CJ --- hypervisor/arch/x86/cpu_caps.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/hypervisor/arch/x86/cpu_caps.c b/hypervisor/arch/x86/cpu_caps.c index d5259aae2..b2b25a4c4 100644 --- a/hypervisor/arch/x86/cpu_caps.c +++ b/hypervisor/arch/x86/cpu_caps.c @@ -218,27 +218,32 @@ static void detect_ept_cap(void) static void detect_apicv_cap(void) { - uint8_t features; + uint8_t features = 0U; uint64_t msr_val; msr_val = msr_read(MSR_IA32_VMX_PROCBASED_CTLS); - if (!is_ctrl_setting_allowed(msr_val, VMX_PROCBASED_CTLS_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)) { + 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 { + /* must support APICV access */ return; } - if (!is_ctrl_setting_allowed(msr_val, VMX_PROCBASED_CTLS2_VAPIC_REGS)) { - return; - } - - features = (VAPIC_FEATURE_TPR_SHADOW - | VAPIC_FEATURE_VIRT_ACCESS - | VAPIC_FEATURE_VIRT_REG); - if (is_ctrl_setting_allowed(msr_val, VMX_PROCBASED_CTLS2_VX2APIC)) { features |= VAPIC_FEATURE_VX2APIC_MODE; } @@ -485,6 +490,7 @@ int32_t detect_hardware_support(void) if (!is_apicv_supported()) { pr_fatal("%s, APICV not supported\n", __func__); + return -ENODEV; } if (boot_cpu_data.cpuid_level < 0x15U) {