From ab2961473fad6fdba90e70c78b9437eb467f3b4b Mon Sep 17 00:00:00 2001 From: Edwin Zhai Date: Tue, 7 Aug 2018 18:06:21 +0800 Subject: [PATCH] HV: VMX reshuffle: put EPT check before enabling Current EPT check runs after EPT enabling in init_exec_ctrl. This patch fixes wrong order. Signed-off-by: Edwin Zhai Acked-by: Eddie Dong --- hypervisor/arch/x86/cpu.c | 41 +++++++++++++++++++++++++++++-- hypervisor/arch/x86/ept.c | 29 ---------------------- hypervisor/arch/x86/vmx.c | 8 ------ hypervisor/include/arch/x86/cpu.h | 1 + hypervisor/include/arch/x86/mmu.h | 1 - 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index 84a8fcf7f..191c93974 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -41,6 +41,7 @@ bool x2apic_enabled = false; struct cpu_capability { uint8_t vapic_features; + uint8_t ept_features; }; static struct cpu_capability cpu_caps; @@ -48,7 +49,7 @@ struct cpuinfo_x86 boot_cpu_data; static void bsp_boot_post(void); static void cpu_secondary_post(void); -static void vapic_cap_detect(void); +static void cpu_cap_detect(void); static void cpu_xsave_init(void); static void set_current_cpu_id(uint16_t pcpu_id); static void print_hv_banner(void); @@ -237,6 +238,11 @@ static int hardware_detect_support(void) return -ENODEV; } + if (!is_ept_supported()) { + pr_fatal("%s, EPT not supported\n", __func__); + return -ENODEV; + } + ret = check_vmx_mmu_cap(); if (ret != 0) { return ret; @@ -484,7 +490,7 @@ static void bsp_boot_post(void) set_fs_base(); #endif - vapic_cap_detect(); + cpu_cap_detect(); cpu_xsave_init(); @@ -838,6 +844,26 @@ static bool is_ctrl_setting_allowed(uint64_t msr_val, uint32_t ctrl) return ((((uint32_t)(msr_val >> 32UL)) & ctrl) == ctrl); } +static void ept_cap_detect(void) +{ + uint64_t msr_val; + + cpu_caps.ept_features = 0U; + + /* Read primary processor based VM control. */ + msr_val = msr_read(MSR_IA32_VMX_PROCBASED_CTLS); + + /* Check if secondary processor based VM control is available. */ + if ((msr_val & (((uint64_t)VMX_PROCBASED_CTLS_SECONDARY) << 32)) == 0U) + return; + + /* Read secondary processor based VM control. */ + msr_val = msr_read(MSR_IA32_VMX_PROCBASED_CTLS2); + + if (is_ctrl_setting_allowed(msr_val, VMX_PROCBASED_CTLS2_EPT)) + cpu_caps.ept_features = 1U; +} + static void vapic_cap_detect(void) { uint8_t features; @@ -880,6 +906,17 @@ static void vapic_cap_detect(void) cpu_caps.vapic_features = features; } +static void cpu_cap_detect(void) +{ + vapic_cap_detect(); + ept_cap_detect(); +} + +bool is_ept_supported(void) +{ + return (cpu_caps.ept_features != 0U); +} + bool is_vapic_supported(void) { return ((cpu_caps.vapic_features & VAPIC_FEATURE_VIRT_ACCESS) != 0U); diff --git a/hypervisor/arch/x86/ept.c b/hypervisor/arch/x86/ept.c index a7bcb43e9..ed1e2455a 100644 --- a/hypervisor/arch/x86/ept.c +++ b/hypervisor/arch/x86/ept.c @@ -144,35 +144,6 @@ uint64_t hpa2gpa(struct vm *vm, uint64_t hpa) | (hpa & (pg_size - 1UL))); } -bool is_ept_supported(void) -{ - bool status; - uint64_t tmp64; - - /* Read primary processor based VM control. */ - tmp64 = msr_read(MSR_IA32_VMX_PROCBASED_CTLS); - - /* Check if secondary processor based VM control is available. */ - if ((tmp64 & MMU_MEM_ATTR_BIT_EXECUTE_DISABLE) != 0U) { - /* Read primary processor based VM control. */ - tmp64 = msr_read(MSR_IA32_VMX_PROCBASED_CTLS2); - - /* Check if EPT is supported. */ - if ((tmp64 & (((uint64_t)VMX_PROCBASED_CTLS2_EPT) << 32)) != 0U) { - /* EPT is present. */ - status = true; - } else { - status = false; - } - - } else { - /* Secondary processor based VM control is not present */ - status = false; - } - - return status; -} - int ept_violation_vmexit_handler(struct vcpu *vcpu) { int status = -EINVAL, ret; diff --git a/hypervisor/arch/x86/vmx.c b/hypervisor/arch/x86/vmx.c index f2778d639..183d36065 100644 --- a/hypervisor/arch/x86/vmx.c +++ b/hypervisor/arch/x86/vmx.c @@ -1054,14 +1054,6 @@ static void init_exec_ctrl(struct vcpu *vcpu) } } - /* Check for EPT support */ - if (is_ept_supported()) { - pr_dbg("EPT is supported"); - } - else { - pr_err("Error: EPT is not supported"); - } - /* Load EPTP execution control * TODO: introduce API to make this data driven based * on VMX_EPT_VPID_CAP diff --git a/hypervisor/include/arch/x86/cpu.h b/hypervisor/include/arch/x86/cpu.h index a29a7c59f..db928ce34 100644 --- a/hypervisor/include/arch/x86/cpu.h +++ b/hypervisor/include/arch/x86/cpu.h @@ -324,6 +324,7 @@ void trampoline_start16(void); bool is_vapic_supported(void); bool is_vapic_intr_delivery_supported(void); bool is_vapic_virt_reg_supported(void); +bool is_ept_supported(void); bool cpu_has_cap(uint32_t bit); void load_cpu_state_data(void); void bsp_boot_init(void); diff --git a/hypervisor/include/arch/x86/mmu.h b/hypervisor/include/arch/x86/mmu.h index 276990354..c534d76c8 100644 --- a/hypervisor/include/arch/x86/mmu.h +++ b/hypervisor/include/arch/x86/mmu.h @@ -376,7 +376,6 @@ static inline void clflush(volatile void *p) } /* External Interfaces */ -bool is_ept_supported(void); uint64_t create_guest_initial_paging(struct vm *vm); void destroy_ept(struct vm *vm); uint64_t gpa2hpa(struct vm *vm, uint64_t gpa);