Commit 878403b7 authored by Sheng Yang's avatar Sheng Yang Committed by Marcelo Tosatti

KVM: VMX: Enable EPT 1GB page support

Signed-off-by: default avatarSheng Yang <sheng@linux.intel.com>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
parent 17cc3935
...@@ -364,6 +364,7 @@ enum vmcs_field { ...@@ -364,6 +364,7 @@ enum vmcs_field {
#define VMX_EPTP_UC_BIT (1ull << 8) #define VMX_EPTP_UC_BIT (1ull << 8)
#define VMX_EPTP_WB_BIT (1ull << 14) #define VMX_EPTP_WB_BIT (1ull << 14)
#define VMX_EPT_2MB_PAGE_BIT (1ull << 16) #define VMX_EPT_2MB_PAGE_BIT (1ull << 16)
#define VMX_EPT_1GB_PAGE_BIT (1ull << 17)
#define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ull << 24) #define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ull << 24)
#define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25) #define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25)
#define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26) #define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26)
......
...@@ -500,8 +500,7 @@ static int host_mapping_level(struct kvm *kvm, gfn_t gfn) ...@@ -500,8 +500,7 @@ static int host_mapping_level(struct kvm *kvm, gfn_t gfn)
static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn) static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
{ {
struct kvm_memory_slot *slot; struct kvm_memory_slot *slot;
int host_level; int host_level, level, max_level;
int level = PT_PAGE_TABLE_LEVEL;
slot = gfn_to_memslot(vcpu->kvm, large_gfn); slot = gfn_to_memslot(vcpu->kvm, large_gfn);
if (slot && slot->dirty_bitmap) if (slot && slot->dirty_bitmap)
...@@ -512,7 +511,10 @@ static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn) ...@@ -512,7 +511,10 @@ static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
if (host_level == PT_PAGE_TABLE_LEVEL) if (host_level == PT_PAGE_TABLE_LEVEL)
return host_level; return host_level;
for (level = PT_DIRECTORY_LEVEL; level <= host_level; ++level) max_level = kvm_x86_ops->get_lpage_level() < host_level ?
kvm_x86_ops->get_lpage_level() : host_level;
for (level = PT_DIRECTORY_LEVEL; level <= max_level; ++level)
if (has_wrprotected_page(vcpu->kvm, large_gfn, level)) if (has_wrprotected_page(vcpu->kvm, large_gfn, level))
break; break;
......
...@@ -318,6 +318,11 @@ static inline bool cpu_has_vmx_ept_2m_page(void) ...@@ -318,6 +318,11 @@ static inline bool cpu_has_vmx_ept_2m_page(void)
return !!(vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT); return !!(vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT);
} }
static inline bool cpu_has_vmx_ept_1g_page(void)
{
return !!(vmx_capability.ept & VMX_EPT_1GB_PAGE_BIT);
}
static inline int cpu_has_vmx_invept_individual_addr(void) static inline int cpu_has_vmx_invept_individual_addr(void)
{ {
return !!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT); return !!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT);
...@@ -4038,7 +4043,11 @@ static const struct trace_print_flags vmx_exit_reasons_str[] = { ...@@ -4038,7 +4043,11 @@ static const struct trace_print_flags vmx_exit_reasons_str[] = {
static int vmx_get_lpage_level(void) static int vmx_get_lpage_level(void)
{ {
return PT_DIRECTORY_LEVEL; if (enable_ept && !cpu_has_vmx_ept_1g_page())
return PT_DIRECTORY_LEVEL;
else
/* For shadow and EPT supported 1GB page */
return PT_PDPE_LEVEL;
} }
static inline u32 bit(int bitno) static inline u32 bit(int bitno)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment