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 <edwin.zhai@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Edwin Zhai 2018-08-07 18:06:21 +08:00 committed by lijinxia
parent 112b4eaa42
commit ab2961473f
5 changed files with 40 additions and 40 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);