aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-06-01 07:13:12 +0100
committerKeir Fraser <keir.fraser@citrix.com>2010-06-01 07:13:12 +0100
commit870e1221020ea1f41ba68ce1af98e19605a40e16 (patch)
tree52844d80e3880e530e099ffc24c96b1c132c9b76
parent0bfde448561e1e6f723e436bd4562e3b7cd764ee (diff)
downloadxen-870e1221020ea1f41ba68ce1af98e19605a40e16.tar.gz
xen-870e1221020ea1f41ba68ce1af98e19605a40e16.tar.bz2
xen-870e1221020ea1f41ba68ce1af98e19605a40e16.zip
EPT 2M super page detection
Signed-off-by: Xin Li <xin.li@intel.com>
-rw-r--r--xen/arch/x86/hvm/svm/svm.c2
-rw-r--r--xen/arch/x86/hvm/vmx/vmcs.c12
-rw-r--r--xen/arch/x86/hvm/vmx/vmx.c7
-rw-r--r--xen/arch/x86/mm/p2m.c4
-rw-r--r--xen/include/asm-x86/hvm/hvm.h12
-rw-r--r--xen/include/asm-x86/hvm/vmx/vmcs.h6
-rw-r--r--xen/include/asm-x86/msr-index.h1
7 files changed, 42 insertions, 2 deletions
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index d1139f3152..8d008a6d70 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -903,6 +903,8 @@ void start_svm(struct cpuinfo_x86 *c)
svm_function_table.hap_supported = cpu_has_svm_npt;
+ svm_function_table.hap_capabilities = HVM_HAP_SUPERPAGE_2MB;
+
hvm_enable(&svm_function_table);
}
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index 108296ff97..7fd9bf03e5 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -64,6 +64,7 @@ u32 vmx_cpu_based_exec_control __read_mostly;
u32 vmx_secondary_exec_control __read_mostly;
u32 vmx_vmexit_control __read_mostly;
u32 vmx_vmentry_control __read_mostly;
+u64 vmx_ept_vpid_cap __read_mostly;
bool_t cpu_has_vmx_ins_outs_instr_info __read_mostly;
static DEFINE_PER_CPU_READ_MOSTLY(struct vmcs_struct *, host_vmcs);
@@ -90,6 +91,9 @@ static void __init vmx_display_features(void)
if ( !printed )
printk(" - none\n");
+
+ if ( cpu_has_vmx_ept_2mb )
+ printk("EPT supports 2MB super page.\n");
}
static u32 adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, u32 msr)
@@ -113,6 +117,7 @@ static void vmx_init_vmcs_config(void)
u32 _vmx_pin_based_exec_control;
u32 _vmx_cpu_based_exec_control;
u32 _vmx_secondary_exec_control = 0;
+ u64 _vmx_ept_vpid_cap = 0;
u32 _vmx_vmexit_control;
u32 _vmx_vmentry_control;
@@ -185,6 +190,11 @@ static void vmx_init_vmcs_config(void)
SECONDARY_EXEC_UNRESTRICTED_GUEST);
}
+ /* The IA32_VMX_EPT_VPID_CAP MSR exists only when EPT or VPID available */
+ if ( _vmx_secondary_exec_control &
+ (SECONDARY_EXEC_ENABLE_EPT | SECONDARY_EXEC_ENABLE_VPID) )
+ rdmsrl(MSR_IA32_VMX_EPT_VPID_CAP, _vmx_ept_vpid_cap);
+
if ( (_vmx_secondary_exec_control & SECONDARY_EXEC_PAUSE_LOOP_EXITING) &&
ple_gap == 0 )
{
@@ -219,6 +229,7 @@ static void vmx_init_vmcs_config(void)
vmx_pin_based_exec_control = _vmx_pin_based_exec_control;
vmx_cpu_based_exec_control = _vmx_cpu_based_exec_control;
vmx_secondary_exec_control = _vmx_secondary_exec_control;
+ vmx_ept_vpid_cap = _vmx_ept_vpid_cap;
vmx_vmexit_control = _vmx_vmexit_control;
vmx_vmentry_control = _vmx_vmentry_control;
cpu_has_vmx_ins_outs_instr_info = !!(vmx_basic_msr_high & (1U<<22));
@@ -231,6 +242,7 @@ static void vmx_init_vmcs_config(void)
BUG_ON(vmx_pin_based_exec_control != _vmx_pin_based_exec_control);
BUG_ON(vmx_cpu_based_exec_control != _vmx_cpu_based_exec_control);
BUG_ON(vmx_secondary_exec_control != _vmx_secondary_exec_control);
+ BUG_ON(vmx_ept_vpid_cap != _vmx_ept_vpid_cap);
BUG_ON(vmx_vmexit_control != _vmx_vmexit_control);
BUG_ON(vmx_vmentry_control != _vmx_vmentry_control);
BUG_ON(cpu_has_vmx_ins_outs_instr_info !=
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 0f1a085812..19981cf0de 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -1444,8 +1444,15 @@ void start_vmx(void)
}
if ( cpu_has_vmx_ept )
+ {
vmx_function_table.hap_supported = 1;
+ vmx_function_table.hap_capabilities = 0;
+
+ if ( cpu_has_vmx_ept_2mb )
+ vmx_function_table.hap_capabilities |= HVM_HAP_SUPERPAGE_2MB;
+ }
+
setup_vmcs_dump();
hvm_enable(&vmx_function_table);
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 5c2e12dd37..9e186ed1ff 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1596,8 +1596,8 @@ int set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
while ( todo )
{
if ( is_hvm_domain(d) && d->arch.hvm_domain.hap_enabled )
- order = (((gfn | mfn_x(mfn) | todo) & (SUPERPAGE_PAGES - 1)) == 0) ?
- 9 : 0;
+ order = ((((gfn | mfn_x(mfn) | todo) & (SUPERPAGE_PAGES - 1)) == 0)
+ && hvm_hap_has_2mb(d)) ? 9 : 0;
else
order = 0;
if ( !d->arch.p2m->set_entry(d, gfn, mfn, order, p2mt) )
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
index 0ae7e7ea0a..080848a8af 100644
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -59,6 +59,12 @@ enum hvm_intblk {
#define HVM_INTR_SHADOW_NMI 0x00000008
/*
+ * HAP super page capabilities:
+ * bit0: if 2MB super page is allowed?
+ */
+#define HVM_HAP_SUPERPAGE_2MB 0x00000001
+
+/*
* The hardware virtual machine (HVM) interface abstracts away from the
* x86/x86_64 CPU virtualization assist specifics. Currently this interface
* supports Intel's VT-x and AMD's SVM extensions.
@@ -69,6 +75,9 @@ struct hvm_function_table {
/* Support Hardware-Assisted Paging? */
int hap_supported;
+ /* Indicate HAP capabilities. */
+ int hap_capabilities;
+
/*
* Initialise/destroy HVM domain/vcpu resources
*/
@@ -163,6 +172,9 @@ int hvm_girq_dest_2_vcpu_id(struct domain *d, uint8_t dest, uint8_t dest_mode);
#define hvm_nx_enabled(v) \
(!!((v)->arch.hvm_vcpu.guest_efer & EFER_NX))
+#define hvm_hap_has_2mb(d) \
+ (hvm_funcs.hap_capabilities & HVM_HAP_SUPERPAGE_2MB)
+
#ifdef __x86_64__
#define hvm_long_mode_enabled(v) \
((v)->arch.hvm_vcpu.guest_efer & EFER_LMA)
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h
index 657ae96252..85b37b3213 100644
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -176,6 +176,10 @@ extern u32 vmx_secondary_exec_control;
extern bool_t cpu_has_vmx_ins_outs_instr_info;
+extern u64 vmx_ept_vpid_cap;
+
+#define VMX_EPT_SUPERPAGE_2MB 0x00010000
+
#define cpu_has_wbinvd_exiting \
(vmx_secondary_exec_control & SECONDARY_EXEC_WBINVD_EXITING)
#define cpu_has_vmx_virtualize_apic_accesses \
@@ -190,6 +194,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr_info;
(vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS)
#define cpu_has_vmx_ept \
(vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT)
+#define cpu_has_vmx_ept_2mb \
+ (vmx_ept_vpid_cap & VMX_EPT_SUPERPAGE_2MB)
#define cpu_has_vmx_vpid \
(vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID)
#define cpu_has_monitor_trap_flag \
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index 486621f4ed..99762e1b78 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -171,6 +171,7 @@
#define MSR_IA32_VMX_CR4_FIXED0 0x488
#define MSR_IA32_VMX_CR4_FIXED1 0x489
#define MSR_IA32_VMX_PROCBASED_CTLS2 0x48b
+#define MSR_IA32_VMX_EPT_VPID_CAP 0x48c
#define MSR_IA32_VMX_TRUE_PINBASED_CTLS 0x48d
#define MSR_IA32_VMX_TRUE_PROCBASED_CTLS 0x48e
#define MSR_IA32_VMX_TRUE_EXIT_CTLS 0x48f