[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH V3] x86/altp2m: propagate ept.ad changes to all active altp2ms
This patch is a pre-requisite for fixing the logdirty VGA issue (display freezes when switching to a new altp2m view early in a domain's lifetime), but sent separately for easier review. The new ept_set_ad_sync() function has been added to update all active altp2ms' ept.ad. New altp2ms will inherit the hostp2m's ept.ad value. ept_set_ad_sync() is now also the code responsible for locking updated p2ms. Signed-off-by: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx> Suggested-by: George Dunlap <george.dunlap@xxxxxxxxxx> --- Changes since V2: - Proper hostp2m locking in ept_{enable,disable}_pml(). - Added two asserts in ept_set_ad_sync(), checking that the passed p2m is the hostp2m, and that it has been locked. --- xen/arch/x86/mm/p2m-ept.c | 64 +++++++++++++++++++++++++++++++++++++++++------ xen/arch/x86/mm/p2m.c | 8 ------ 2 files changed, 56 insertions(+), 16 deletions(-) diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c index d376966..3d228c2 100644 --- a/xen/arch/x86/mm/p2m-ept.c +++ b/xen/arch/x86/mm/p2m-ept.c @@ -17,6 +17,7 @@ #include <xen/domain_page.h> #include <xen/sched.h> +#include <asm/altp2m.h> #include <asm/current.h> #include <asm/paging.h> #include <asm/types.h> @@ -1218,34 +1219,79 @@ static void ept_tlb_flush(struct p2m_domain *p2m) ept_sync_domain_mask(p2m, p2m->domain->dirty_cpumask); } +static void ept_set_ad_sync(struct p2m_domain *hostp2m, bool value) +{ + struct domain *d = hostp2m->domain; + + ASSERT(p2m_is_hostp2m(hostp2m)); + ASSERT(p2m_locked_by_me(hostp2m)); + + hostp2m->ept.ad = value; + + if ( unlikely(altp2m_active(d)) ) + { + unsigned int i; + + for ( i = 0; i < MAX_ALTP2M; i++ ) + { + struct p2m_domain *p2m; + + if ( d->arch.altp2m_eptp[i] == mfn_x(INVALID_MFN) ) + continue; + + p2m = d->arch.altp2m_p2m[i]; + + p2m_lock(p2m); + p2m->ept.ad = value; + p2m_unlock(p2m); + } + } +} + static void ept_enable_pml(struct p2m_domain *p2m) { + struct domain *d = p2m->domain; + struct p2m_domain *hostp2m = p2m_get_hostp2m(d); + + p2m_lock(hostp2m); + /* Domain must have been paused */ - ASSERT(atomic_read(&p2m->domain->pause_count)); + ASSERT(atomic_read(&d->pause_count)); /* * No need to return whether vmx_domain_enable_pml has succeeded, as * ept_p2m_type_to_flags will do the check, and write protection will be * used if PML is not enabled. */ - if ( vmx_domain_enable_pml(p2m->domain) ) + if ( vmx_domain_enable_pml(d) ) return; /* Enable EPT A/D bit for PML */ - p2m->ept.ad = 1; - vmx_domain_update_eptp(p2m->domain); + ept_set_ad_sync(hostp2m, true); + + vmx_domain_update_eptp(d); + + p2m_unlock(hostp2m); } static void ept_disable_pml(struct p2m_domain *p2m) { + struct domain *d = p2m->domain; + struct p2m_domain *hostp2m = p2m_get_hostp2m(d); + + p2m_lock(hostp2m); + /* Domain must have been paused */ - ASSERT(atomic_read(&p2m->domain->pause_count)); + ASSERT(atomic_read(&d->pause_count)); - vmx_domain_disable_pml(p2m->domain); + vmx_domain_disable_pml(d); /* Disable EPT A/D bit */ - p2m->ept.ad = 0; - vmx_domain_update_eptp(p2m->domain); + ept_set_ad_sync(hostp2m, false); + + vmx_domain_update_eptp(d); + + p2m_unlock(hostp2m); } static void ept_flush_pml_buffers(struct p2m_domain *p2m) @@ -1386,8 +1432,10 @@ void setup_ept_dump(void) void p2m_init_altp2m_ept(struct domain *d, unsigned int i) { struct p2m_domain *p2m = d->arch.altp2m_p2m[i]; + struct p2m_domain *hostp2m = p2m_get_hostp2m(d); struct ept_data *ept; + p2m->ept.ad = hostp2m->ept.ad; p2m->min_remapped_gfn = gfn_x(INVALID_GFN); p2m->max_remapped_gfn = 0; ept = &p2m->ept; diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index d6a8810..d90c624 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -360,11 +360,7 @@ void p2m_enable_hardware_log_dirty(struct domain *d) struct p2m_domain *p2m = p2m_get_hostp2m(d); if ( p2m->enable_hardware_log_dirty ) - { - p2m_lock(p2m); p2m->enable_hardware_log_dirty(p2m); - p2m_unlock(p2m); - } } void p2m_disable_hardware_log_dirty(struct domain *d) @@ -372,11 +368,7 @@ void p2m_disable_hardware_log_dirty(struct domain *d) struct p2m_domain *p2m = p2m_get_hostp2m(d); if ( p2m->disable_hardware_log_dirty ) - { - p2m_lock(p2m); p2m->disable_hardware_log_dirty(p2m); - p2m_unlock(p2m); - } } void p2m_flush_hardware_cached_dirty(struct domain *d) -- 2.7.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |