[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] VMX: enforce EPT paging structure memory type and page-walk length check.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1276165082 -3600 # Node ID def12332b19c40f8600e788b749a3de893faabaa # Parent 1bfab8704f32471fd942bd538bb3aec327188451 VMX: enforce EPT paging structure memory type and page-walk length check. Also use a macro to get EPT walk length. signed-off-by: Xin Li <xin.li@xxxxxxxxx> --- xen/arch/x86/hvm/vmx/vmcs.c | 25 ++++++++++++++++++++----- xen/arch/x86/hvm/vmx/vmx.c | 9 ++++++--- xen/arch/x86/mm/hap/p2m-ept.c | 14 ++++++-------- xen/include/asm-x86/hvm/vmx/vmcs.h | 23 +++++++++++------------ xen/include/asm-x86/hvm/vmx/vmx.h | 14 ++++++++++++++ 5 files changed, 57 insertions(+), 28 deletions(-) diff -r 1bfab8704f32 -r def12332b19c xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Thu Jun 10 10:18:00 2010 +0100 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Thu Jun 10 11:18:02 2010 +0100 @@ -192,6 +192,26 @@ static int vmx_init_vmcs_config(void) MSR_IA32_VMX_PROCBASED_CTLS2, &mismatch); } + /* 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); + + /* + * Additional sanity checking before using EPT: + * 1) the CPU we are running on must support EPT WB, as we will set + * ept paging structures memory type to WB; + * 2) the CPU must support the EPT page-walk length of 4 according to + * Intel SDM 25.2.2. + * + * Or we just don't use EPT. + */ + if ( !(_vmx_ept_vpid_cap & VMX_EPT_MEMORY_TYPE_WB) || + !(_vmx_ept_vpid_cap & VMX_EPT_WALK_LENGTH_4_SUPPORTED) ) + _vmx_secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_EPT; + } + if ( _vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT ) { /* @@ -209,11 +229,6 @@ static int vmx_init_vmcs_config(void) ~(SECONDARY_EXEC_ENABLE_EPT | 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 ) diff -r 1bfab8704f32 -r def12332b19c xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Thu Jun 10 10:18:00 2010 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Jun 10 11:18:02 2010 +0100 @@ -78,11 +78,14 @@ static int vmx_domain_initialise(struct { int rc; - d->arch.hvm_domain.vmx.ept_control.etmt = EPT_DEFAULT_MT; - d->arch.hvm_domain.vmx.ept_control.gaw = EPT_DEFAULT_GAW; + /* Set the memory type used when accessing EPT paging structures. */ + d->arch.hvm_domain.vmx.ept_control.ept_mt = EPT_DEFAULT_MT; + + /* set EPT page-walk length, now it's actual walk length - 1, i.e. 3 */ + d->arch.hvm_domain.vmx.ept_control.ept_wl = 3; + d->arch.hvm_domain.vmx.ept_control.asr = pagetable_get_pfn(p2m_get_pagetable(p2m_get_hostp2m(d))); - if ( (rc = vmx_alloc_vlapic_mapping(d)) != 0 ) return rc; diff -r 1bfab8704f32 -r def12332b19c xen/arch/x86/mm/hap/p2m-ept.c --- a/xen/arch/x86/mm/hap/p2m-ept.c Thu Jun 10 10:18:00 2010 +0100 +++ b/xen/arch/x86/mm/hap/p2m-ept.c Thu Jun 10 11:18:02 2010 +0100 @@ -253,7 +253,7 @@ ept_set_entry(struct domain *d, unsigned ASSERT(table != NULL); - for ( i = EPT_DEFAULT_GAW; i > walk_level; i-- ) + for ( i = ept_get_wl(d); i > walk_level; i-- ) { ret = ept_next_level(d, 0, &table, &gfn_remainder, i * EPT_TABLE_ORDER); if ( !ret ) @@ -402,7 +402,7 @@ static mfn_t ept_get_entry(struct domain /* Should check if gfn obeys GAW here. */ - for ( i = EPT_DEFAULT_GAW; i > 0; i-- ) + for ( i = ept_get_wl(d); i > 0; i-- ) { retry: ret = ept_next_level(d, 1, &table, &gfn_remainder, @@ -492,7 +492,7 @@ static ept_entry_t ept_get_entry_content if ( gfn > d->arch.p2m->max_mapped_pfn ) goto out; - for ( i = EPT_DEFAULT_GAW; i > 0; i-- ) + for ( i = ept_get_wl(d); i > 0; i-- ) { ret = ept_next_level(d, 1, &table, &gfn_remainder, i * EPT_TABLE_ORDER); @@ -531,7 +531,7 @@ void ept_walk_table(struct domain *d, un goto out; } - for ( i = EPT_DEFAULT_GAW; i >= 0; i-- ) + for ( i = ept_get_wl(d); i >= 0; i-- ) { ept_entry_t *ept_entry, *next; u32 index; @@ -658,8 +658,6 @@ static void ept_change_entry_type_global if ( pagetable_get_pfn(p2m_get_pagetable(p2m_get_hostp2m(d))) == 0 ) return; - BUG_ON(EPT_DEFAULT_GAW != 3); - l4e = map_domain_page(mfn_x(pagetable_get_mfn(p2m_get_pagetable(p2m_get_hostp2m(d))))); for (i4 = 0; i4 < EPT_PAGETABLE_ENTRIES; i4++ ) { @@ -751,7 +749,7 @@ static void ept_dump_p2m_table(unsigned int order; int i; int is_pod; - int ret; + int ret = 0; unsigned long index; unsigned long gfn, gfn_remainder; unsigned long record_counter = 0; @@ -772,7 +770,7 @@ static void ept_dump_p2m_table(unsigned table = map_domain_page(mfn_x(pagetable_get_mfn(p2m_get_pagetable(p2m)))); - for ( i = EPT_DEFAULT_GAW; i > 0; i-- ) + for ( i = ept_get_wl(d); i > 0; i-- ) { ret = ept_next_level(d, 1, &table, &gfn_remainder, i * EPT_TABLE_ORDER); diff -r 1bfab8704f32 -r def12332b19c xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Thu Jun 10 10:18:00 2010 +0100 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Thu Jun 10 11:18:02 2010 +0100 @@ -55,22 +55,24 @@ struct vmx_msr_state { unsigned long msrs[VMX_MSR_COUNT]; }; -#define EPT_DEFAULT_MT 6 -#define EPT_DEFAULT_GAW 3 +#define EPT_DEFAULT_MT MTRR_TYPE_WRBACK struct vmx_domain { unsigned long apic_access_mfn; union { struct { - u64 etmt :3, - gaw :3, - rsvd :6, - asr :52; + u64 ept_mt :3, + ept_wl :3, + rsvd :6, + asr :52; }; u64 eptp; } ept_control; cpumask_t ept_synced; }; + +#define ept_get_wl(d) \ + ((d)->arch.hvm_domain.vmx.ept_control.ept_wl) struct arch_vmx_struct { /* Virtual address of VMCS. */ @@ -174,8 +176,9 @@ 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_WALK_LENGTH_4_SUPPORTED 0x00000040 +#define VMX_EPT_MEMORY_TYPE_UC 0x00000100 +#define VMX_EPT_MEMORY_TYPE_WB 0x00004000 #define VMX_EPT_SUPERPAGE_2MB 0x00010000 #define VMX_EPT_SUPERPAGE_1GB 0x00020000 @@ -193,10 +196,6 @@ extern u64 vmx_ept_vpid_cap; (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 \ diff -r 1bfab8704f32 -r def12332b19c xen/include/asm-x86/hvm/vmx/vmx.h --- a/xen/include/asm-x86/hvm/vmx/vmx.h Thu Jun 10 10:18:00 2010 +0100 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h Thu Jun 10 11:18:02 2010 +0100 @@ -184,6 +184,20 @@ void vmx_update_debug_state(struct vcpu #define MODRM_EAX_07 ".byte 0x38\n" /* [EAX], with reg/opcode: /7 */ #define MODRM_EAX_ECX ".byte 0xc1\n" /* EAX, ECX */ +extern u64 vmx_ept_vpid_cap; + +#define cpu_has_vmx_ept_wl4_supported \ + (vmx_ept_vpid_cap & VMX_EPT_WALK_LENGTH_4_SUPPORTED) +#define cpu_has_vmx_ept_mt_uc \ + (vmx_ept_vpid_cap & VMX_EPT_MEMORY_TYPE_UC) +#define cpu_has_vmx_ept_mt_wb \ + (vmx_ept_vpid_cap & VMX_EPT_MEMORY_TYPE_WB) +#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) + + static inline void __vmptrld(u64 addr) { asm volatile ( VMPTRLD_OPCODE _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |