[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] VMX: does EPT capabilities detection strictly according to Intel SDM.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1275398759 -3600 # Node ID 267ecb2ee5bfab4f25b3b5b5cb99f5b1a72fa87c # Parent 188e3da0aa2746f2f0cecce9f099a03554755125 VMX: does EPT capabilities detection strictly according to Intel SDM. Signed-off-by: Xin Li <xin.li@xxxxxxxxx> --- xen/arch/x86/hvm/svm/svm.c | 4 +-- xen/arch/x86/hvm/vmx/vmcs.c | 39 +++++++++++++++---------------------- xen/arch/x86/hvm/vmx/vmx.c | 10 +++++++-- xen/arch/x86/mm/hap/p2m-ept.c | 11 +++++++--- xen/arch/x86/mm/p2m.c | 7 ++---- xen/include/asm-x86/hvm/hvm.h | 20 ++++++++++++++---- xen/include/asm-x86/hvm/vmx/vmcs.h | 14 +++++++------ 7 files changed, 60 insertions(+), 45 deletions(-) diff -r 188e3da0aa27 -r 267ecb2ee5bf xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Tue Jun 01 13:57:44 2010 +0100 +++ b/xen/arch/x86/hvm/svm/svm.c Tue Jun 01 14:25:59 2010 +0100 @@ -935,9 +935,9 @@ struct hvm_function_table * __init start cpuid_edx(0x8000000A) : 0); svm_function_table.hap_supported = cpu_has_svm_npt; - svm_function_table.hap_superpage_level = + svm_function_table.hap_capabilities = HVM_HAP_SUPERPAGE_2MB | ((CONFIG_PAGING_LEVELS == 4) && (cpuid_edx(0x80000001) & 0x04000000)) ? - 2 : 1; + HVM_HAP_SUPERPAGE_1GB : 0; return &svm_function_table; } diff -r 188e3da0aa27 -r 267ecb2ee5bf xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Tue Jun 01 13:57:44 2010 +0100 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Tue Jun 01 14:25:59 2010 +0100 @@ -64,7 +64,7 @@ u32 vmx_secondary_exec_control __read_mo u32 vmx_secondary_exec_control __read_mostly; u32 vmx_vmexit_control __read_mostly; u32 vmx_vmentry_control __read_mostly; -u8 vmx_ept_super_page_level_limit __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); @@ -92,10 +92,10 @@ static void __init vmx_display_features( if ( !printed ) printk(" - none\n"); - if ( vmx_ept_super_page_level_limit ) - printk("EPT supports %s super page.\n", - (vmx_ept_super_page_level_limit == 2) ? "1G" : - ((vmx_ept_super_page_level_limit == 1) ? "2M" : "4K")); + if ( cpu_has_vmx_ept_1gb ) + printk("EPT supports 1GB super page.\n"); + if ( cpu_has_vmx_ept_2mb ) + printk("EPT supports 2MB super page.\n"); } static u32 adjust_vmx_controls( @@ -132,7 +132,7 @@ static int vmx_init_vmcs_config(void) u32 _vmx_pin_based_exec_control; u32 _vmx_cpu_based_exec_control; u32 _vmx_secondary_exec_control = 0; - u8 ept_super_page_level_limit = 0; + u64 _vmx_ept_vpid_cap = 0; u32 _vmx_vmexit_control; u32 _vmx_vmentry_control; bool_t mismatch = 0; @@ -208,16 +208,12 @@ static int vmx_init_vmcs_config(void) _vmx_secondary_exec_control &= ~(SECONDARY_EXEC_ENABLE_EPT | SECONDARY_EXEC_UNRESTRICTED_GUEST); - if ( _vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT ) - { - uint64_t cap; - rdmsrl(MSR_IA32_VMX_EPT_VPID_CAP, cap); - if ( cap & VMX_EPT_SUPER_PAGE_1G ) - ept_super_page_level_limit = 2; - else if ( cap & VMX_EPT_SUPER_PAGE_2M ) - ept_super_page_level_limit = 1; - } - } + } + + /* 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 ) @@ -256,7 +252,7 @@ static int 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_super_page_level_limit = ept_super_page_level_limit; + 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)); @@ -283,12 +279,9 @@ static int vmx_init_vmcs_config(void) mismatch |= cap_check( "VMEntry Control", vmx_vmentry_control, _vmx_vmentry_control); - if ( vmx_ept_super_page_level_limit > ept_super_page_level_limit ) - { - printk("EPT Super Page Limit: saw %u expected >= %u\n", - ept_super_page_level_limit, vmx_ept_super_page_level_limit); - mismatch = 1; - } + mismatch |= cap_check( + "EPT Super Page Capability", + vmx_ept_vpid_cap, _vmx_ept_vpid_cap); if ( cpu_has_vmx_ins_outs_instr_info != !!(vmx_basic_msr_high & (1U<<22)) ) { diff -r 188e3da0aa27 -r 267ecb2ee5bf xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Tue Jun 01 13:57:44 2010 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Jun 01 14:25:59 2010 +0100 @@ -1432,10 +1432,16 @@ struct hvm_function_table * __init start 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; + if ( cpu_has_vmx_ept_1gb ) + vmx_function_table.hap_capabilities |= HVM_HAP_SUPERPAGE_1GB; + setup_ept_dump(); } - - vmx_function_table.hap_superpage_level = vmx_ept_super_page_level_limit; setup_vmcs_dump(); diff -r 188e3da0aa27 -r 267ecb2ee5bf xen/arch/x86/mm/hap/p2m-ept.c --- a/xen/arch/x86/mm/hap/p2m-ept.c Tue Jun 01 13:57:44 2010 +0100 +++ b/xen/arch/x86/mm/hap/p2m-ept.c Tue Jun 01 14:25:59 2010 +0100 @@ -308,9 +308,14 @@ ept_set_entry(struct domain *d, unsigned int num = order / EPT_TABLE_ORDER; int level; ept_entry_t *split_ept_entry; - - if ( num >= cpu_vmx_ept_super_page_level_limit ) - num = cpu_vmx_ept_super_page_level_limit; + + if ( (num >= 2) && hvm_hap_has_1gb(d) ) + num = 2; + else if ( (num >= 1) && hvm_hap_has_2mb(d) ) + num = 1; + else + num = 0; + for ( level = split_level; level > num ; level-- ) { rv = ept_split_large_page(d, &table, &index, gfn, level); diff -r 188e3da0aa27 -r 267ecb2ee5bf xen/arch/x86/mm/p2m.c --- a/xen/arch/x86/mm/p2m.c Tue Jun 01 13:57:44 2010 +0100 +++ b/xen/arch/x86/mm/p2m.c Tue Jun 01 14:25:59 2010 +0100 @@ -1758,10 +1758,9 @@ int set_p2m_entry(struct domain *d, unsi { if ( is_hvm_domain(d) && paging_mode_hap(d) ) order = ( (((gfn | mfn_x(mfn) | todo) & ((1ul << 18) - 1)) == 0) && - (hvm_funcs.hap_superpage_level == 2) && - opt_hap_1gb ) ? 18 : - ((((gfn | mfn_x(mfn) | todo) & ((1ul << 9) - 1)) == 0) && - (hvm_funcs.hap_superpage_level >= 1)) ? 9 : 0; + hvm_hap_has_1gb(d) && opt_hap_1gb ) ? 18 : + ((((gfn | mfn_x(mfn) | todo) & ((1ul << 9) - 1)) == 0) && + hvm_hap_has_2mb(d)) ? 9 : 0; else order = 0; diff -r 188e3da0aa27 -r 267ecb2ee5bf xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h Tue Jun 01 13:57:44 2010 +0100 +++ b/xen/include/asm-x86/hvm/hvm.h Tue Jun 01 14:25:59 2010 +0100 @@ -62,6 +62,14 @@ enum hvm_intblk { #define HVM_INTR_SHADOW_NMI 0x00000008 /* + * HAP super page capabilities: + * bit0: if 2MB super page is allowed? + * bit1: if 1GB super page is allowed? + */ +#define HVM_HAP_SUPERPAGE_2MB 0x00000001 +#define HVM_HAP_SUPERPAGE_1GB 0x00000002 + +/* * 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. @@ -72,11 +80,8 @@ struct hvm_function_table { /* Support Hardware-Assisted Paging? */ int hap_supported; - /* - * Indicate HAP super page level. - * 0 -- 4KB, 1 -- 2MB, 2 -- 1GB. - */ - int hap_superpage_level; + /* Indicate HAP capabilities. */ + int hap_capabilities; /* @@ -176,6 +181,11 @@ int hvm_girq_dest_2_vcpu_id(struct domai #define hvm_nx_enabled(v) \ (!!((v)->arch.hvm_vcpu.guest_efer & EFER_NX)) +#define hvm_hap_has_1gb(d) \ + (hvm_funcs.hap_capabilities & HVM_HAP_SUPERPAGE_1GB) +#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 -r 188e3da0aa27 -r 267ecb2ee5bf xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Tue Jun 01 13:57:44 2010 +0100 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Tue Jun 01 14:25:59 2010 +0100 @@ -174,10 +174,10 @@ extern u32 vmx_secondary_exec_control; extern bool_t cpu_has_vmx_ins_outs_instr_info; -extern u8 vmx_ept_super_page_level_limit; - -#define VMX_EPT_SUPER_PAGE_2M 0x00010000 -#define VMX_EPT_SUPER_PAGE_1G 0x00020000 +extern u64 vmx_ept_vpid_cap; + +#define VMX_EPT_SUPERPAGE_2MB 0x00010000 +#define VMX_EPT_SUPERPAGE_1GB 0x00020000 #define cpu_has_wbinvd_exiting \ (vmx_secondary_exec_control & SECONDARY_EXEC_WBINVD_EXITING) @@ -193,6 +193,10 @@ extern u8 vmx_ept_super_page_level_limit (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_1gb \ + (vmx_ept_vpid_cap & VMX_EPT_SUPERPAGE_1GB) +#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 \ @@ -206,8 +210,6 @@ extern u8 vmx_ept_super_page_level_limit SECONDARY_EXEC_UNRESTRICTED_GUEST) #define cpu_has_vmx_ple \ (vmx_secondary_exec_control & SECONDARY_EXEC_PAUSE_LOOP_EXITING) -#define cpu_vmx_ept_super_page_level_limit \ - vmx_ept_super_page_level_limit /* GUEST_INTERRUPTIBILITY_INFO flags. */ #define VMX_INTR_SHADOW_STI 0x00000001 _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |