KVM: MMU: Add 5 level EPT & Shadow page table support.
Extends the shadow paging code, so that 5 level shadow page table can be constructed if VM is running in 5 level paging mode. Also extends the ept code, so that 5 level ept table can be constructed if maxphysaddr of VM exceeds 48 bits. Unlike the shadow logic, KVM should still use 4 level ept table for a VM whose physical address width is less than 48 bits, even when the VM is running in 5 level paging mode. Signed-off-by: Yu Zhang <yu.c.zhang@linux.intel.com> [Unconditionally reset the MMU context in kvm_cpuid_update. Changing MAXPHYADDR invalidates the reserved bit bitmasks. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
@@ -1207,6 +1207,11 @@ static inline bool cpu_has_vmx_ept_mt_wb(void)
|
||||
return vmx_capability.ept & VMX_EPTP_WB_BIT;
|
||||
}
|
||||
|
||||
static inline bool cpu_has_vmx_ept_5levels(void)
|
||||
{
|
||||
return vmx_capability.ept & VMX_EPT_PAGE_WALK_5_BIT;
|
||||
}
|
||||
|
||||
static inline bool cpu_has_vmx_ept_ad_bits(void)
|
||||
{
|
||||
return vmx_capability.ept & VMX_EPT_AD_BIT;
|
||||
@@ -4304,9 +4309,18 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
|
||||
vmx->emulation_required = emulation_required(vcpu);
|
||||
}
|
||||
|
||||
static int get_ept_level(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (cpu_has_vmx_ept_5levels() && (cpuid_maxphyaddr(vcpu) > 48))
|
||||
return 5;
|
||||
return 4;
|
||||
}
|
||||
|
||||
static u64 construct_eptp(struct kvm_vcpu *vcpu, unsigned long root_hpa)
|
||||
{
|
||||
u64 eptp = VMX_EPTP_MT_WB | VMX_EPTP_PWL_4;
|
||||
u64 eptp = VMX_EPTP_MT_WB;
|
||||
|
||||
eptp |= (get_ept_level(vcpu) == 5) ? VMX_EPTP_PWL_5 : VMX_EPTP_PWL_4;
|
||||
|
||||
if (enable_ept_ad_bits &&
|
||||
(!is_guest_mode(vcpu) || nested_ept_ad_enabled(vcpu)))
|
||||
@@ -9612,11 +9626,6 @@ static void __init vmx_check_processor_compat(void *rtn)
|
||||
}
|
||||
}
|
||||
|
||||
static int get_ept_level(void)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
|
||||
{
|
||||
u8 cache;
|
||||
|
Reference in New Issue
Block a user