From cd01ef0908ee6d0931ea15ff25606f76fe859757 Mon Sep 17 00:00:00 2001 From: Kai Huang Date: Wed, 14 Oct 2015 17:01:24 +0800 Subject: [PATCH] x86/ept: defer enabling EPT A/D bit until PML is enabled. Signed-off-by: Kai Huang --- xen/arch/x86/hvm/vmx/vmcs.c | 20 ++++++++++++++++++++ xen/arch/x86/mm/p2m-ept.c | 2 -- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 3592a88..9bb278b 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -1382,6 +1382,8 @@ bool_t vmx_vcpu_pml_enabled(const struct vcpu *v) int vmx_vcpu_enable_pml(struct vcpu *v) { + struct p2m_domain *p2m = p2m_get_hostp2m(v->domain); + if ( vmx_vcpu_pml_enabled(v) ) return 0; @@ -1399,6 +1401,9 @@ int vmx_vcpu_enable_pml(struct vcpu *v) __vmwrite(SECONDARY_VM_EXEC_CONTROL, v->arch.hvm_vmx.secondary_exec_control); + /* we leave ept_sync_domain to vmx_domain_enable_pml */ + __vmwrite(EPT_POINTER, ept_get_eptp(&p2m->ept)); + vmx_vmcs_exit(v); return 0; @@ -1406,6 +1411,8 @@ int vmx_vcpu_enable_pml(struct vcpu *v) void vmx_vcpu_disable_pml(struct vcpu *v) { + struct p2m_domain *p2m = p2m_get_hostp2m(v->domain); + if ( !vmx_vcpu_pml_enabled(v) ) return; @@ -1418,6 +1425,9 @@ void vmx_vcpu_disable_pml(struct vcpu *v) __vmwrite(SECONDARY_VM_EXEC_CONTROL, v->arch.hvm_vmx.secondary_exec_control); + /* we leave ept_sync_domain to vmx_domain_enable_pml */ + __vmwrite(EPT_POINTER, ept_get_eptp(&p2m->ept)); + vmx_vmcs_exit(v); v->domain->arch.paging.free_page(v->domain, v->arch.hvm_vmx.pml_pg); @@ -1492,6 +1502,7 @@ bool_t vmx_domain_pml_enabled(const struct domain *d) */ int vmx_domain_enable_pml(struct domain *d) { + struct p2m_domain *p2m = p2m_get_hostp2m(d); struct vcpu *v; int rc; @@ -1500,10 +1511,14 @@ int vmx_domain_enable_pml(struct domain *d) if ( vmx_domain_pml_enabled(d) ) return 0; + p2m->ept.ept_ad = 1; + for_each_vcpu( d, v ) if ( (rc = vmx_vcpu_enable_pml(v)) != 0 ) goto error; + ept_sync_domain(p2m); + d->arch.hvm_domain.vmx.status |= VMX_DOMAIN_PML_ENABLED; return 0; @@ -1523,6 +1538,7 @@ int vmx_domain_enable_pml(struct domain *d) */ void vmx_domain_disable_pml(struct domain *d) { + struct p2m_domain *p2m = p2m_get_hostp2m(d); struct vcpu *v; ASSERT(atomic_read(&d->pause_count)); @@ -1530,10 +1546,14 @@ void vmx_domain_disable_pml(struct domain *d) if ( !vmx_domain_pml_enabled(d) ) return; + p2m->ept.ept_ad = 0; + for_each_vcpu( d, v ) vmx_vcpu_disable_pml(v); d->arch.hvm_domain.vmx.status &= ~VMX_DOMAIN_PML_ENABLED; + + ept_sync_domain(p2m); } /* diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c index 74ce9e0..0d689b0 100644 --- a/xen/arch/x86/mm/p2m-ept.c +++ b/xen/arch/x86/mm/p2m-ept.c @@ -1166,8 +1166,6 @@ int ept_p2m_init(struct p2m_domain *p2m) if ( cpu_has_vmx_pml ) { - /* Enable EPT A/D bits if we are going to use PML. */ - ept->ept_ad = cpu_has_vmx_pml ? 1 : 0; p2m->enable_hardware_log_dirty = ept_enable_pml; p2m->disable_hardware_log_dirty = ept_disable_pml; p2m->flush_hardware_cached_dirty = ept_flush_pml_buffers; -- 2.1.4