[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-4.0-testing] VMX: enforce EPT paging structure memory type and page-walk length check.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1276597837 -3600 # Node ID 3a79e76408aee550a9e644325c5c05aa1b20b2fe # Parent 8375005e6834265765c6cbc8aed6a7a7aac7b7dd 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-unstable changeset: 21591:def12332b19c xen-unstable date: Thu Jun 10 11:18:02 2010 +0100 --- xen/arch/x86/hvm/vmx/vmcs.c | 25 ++++++++++++++++++++----- xen/arch/x86/hvm/vmx/vmx.c | 8 ++++++-- xen/arch/x86/mm/hap/p2m-ept.c | 10 ++++------ xen/include/asm-x86/hvm/vmx/vmcs.h | 21 +++++++++++---------- xen/include/asm-x86/hvm/vmx/vmx.h | 12 ++++++++++++ 5 files changed, 53 insertions(+), 23 deletions(-) diff -r 8375005e6834 -r 3a79e76408ae xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Tue Jun 15 11:30:08 2010 +0100 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Tue Jun 15 11:30:37 2010 +0100 @@ -172,6 +172,26 @@ static void vmx_init_vmcs_config(void) min, opt, MSR_IA32_VMX_PROCBASED_CTLS2); } + /* 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 ) { /* @@ -189,11 +209,6 @@ static void 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 8375005e6834 -r 3a79e76408ae xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Tue Jun 15 11:30:08 2010 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Jun 15 11:30:37 2010 +0100 @@ -78,8 +78,12 @@ 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(d->arch.phys_table); diff -r 8375005e6834 -r 3a79e76408ae xen/arch/x86/mm/hap/p2m-ept.c --- a/xen/arch/x86/mm/hap/p2m-ept.c Tue Jun 15 11:30:08 2010 +0100 +++ b/xen/arch/x86/mm/hap/p2m-ept.c Tue Jun 15 11:30:37 2010 +0100 @@ -200,7 +200,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 ) @@ -394,7 +394,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, @@ -484,7 +484,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); @@ -522,7 +522,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; @@ -646,8 +646,6 @@ static void ept_change_entry_type_global if ( pagetable_get_pfn(d->arch.phys_table) == 0 ) return; - - BUG_ON(EPT_DEFAULT_GAW != 3); l4e = map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table))); for (i4 = 0; i4 < EPT_PAGETABLE_ENTRIES; i4++ ) diff -r 8375005e6834 -r 3a79e76408ae xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Tue Jun 15 11:30:08 2010 +0100 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Tue Jun 15 11:30:37 2010 +0100 @@ -54,22 +54,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. */ @@ -176,8 +178,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 cpu_has_wbinvd_exiting \ @@ -194,8 +197,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_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 8375005e6834 -r 3a79e76408ae xen/include/asm-x86/hvm/vmx/vmx.h --- a/xen/include/asm-x86/hvm/vmx/vmx.h Tue Jun 15 11:30:08 2010 +0100 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h Tue Jun 15 11:30:37 2010 +0100 @@ -184,6 +184,18 @@ 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_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 |