[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH V2 2/3] x86/mm: allocate logdirty_ranges for altp2ms
This patch is a pre-requisite for the one fixing VGA logdirty freezes when using altp2m. It only concerns itself with the ranges allocation / deallocation / initialization part. While touching the code, I've switched global_logdirty from bool_t to bool. Signed-off-by: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx> --- xen/arch/x86/mm/p2m-ept.c | 15 ++++++++++- xen/arch/x86/mm/p2m.c | 55 ++++++++++++++++++++++++++------------- xen/include/asm-x86/hvm/vmx/vmx.h | 2 +- xen/include/asm-x86/p2m.h | 5 +++- 4 files changed, 56 insertions(+), 21 deletions(-) diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c index fabcd06..989917c 100644 --- a/xen/arch/x86/mm/p2m-ept.c +++ b/xen/arch/x86/mm/p2m-ept.c @@ -1348,6 +1348,8 @@ int ept_p2m_init(struct p2m_domain *p2m) void ept_p2m_uninit(struct p2m_domain *p2m) { struct ept_data *ept = &p2m->ept; + + p2m_free_logdirty(p2m); free_cpumask_var(ept->invalidate); } @@ -1434,11 +1436,20 @@ void setup_ept_dump(void) register_keyhandler('D', ept_dump_p2m_table, "dump VT-x EPT tables", 0); } -void p2m_init_altp2m_ept(struct domain *d, unsigned int i) +int 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; + int rc = p2m_init_logdirty(p2m); + + if ( rc ) + return rc; + + rc = rangeset_merge(p2m->logdirty_ranges, hostp2m->logdirty_ranges); + + if ( rc ) + return rc; p2m->ept.ad = hostp2m->ept.ad; p2m->min_remapped_gfn = gfn_x(INVALID_GFN); @@ -1446,6 +1457,8 @@ void p2m_init_altp2m_ept(struct domain *d, unsigned int i) ept = &p2m->ept; ept->mfn = pagetable_get_pfn(p2m_get_pagetable(p2m)); d->arch.altp2m_eptp[i] = ept->eptp; + + return 0; } unsigned int p2m_find_altp2m_by_eptp(struct domain *d, uint64_t eptp) diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 42b9ef4..b37db06 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -113,22 +113,44 @@ static void p2m_free_one(struct p2m_domain *p2m) xfree(p2m); } +int p2m_init_logdirty(struct p2m_domain *p2m) +{ + if ( p2m->logdirty_ranges ) + return 0; + + p2m->logdirty_ranges = rangeset_new(p2m->domain, "log-dirty", + RANGESETF_prettyprint_hex); + if ( !p2m->logdirty_ranges ) + return -ENOMEM; + + return 0; +} + +void p2m_free_logdirty(struct p2m_domain *p2m) +{ + if ( !p2m->logdirty_ranges ) + return; + + rangeset_destroy(p2m->logdirty_ranges); + p2m->logdirty_ranges = NULL; +} + static int p2m_init_hostp2m(struct domain *d) { struct p2m_domain *p2m = p2m_init_one(d); + int rc; - if ( p2m ) - { - p2m->logdirty_ranges = rangeset_new(d, "log-dirty", - RANGESETF_prettyprint_hex); - if ( p2m->logdirty_ranges ) - { - d->arch.p2m = p2m; - return 0; - } + if ( !p2m ) + return -ENOMEM; + + rc = p2m_init_logdirty(p2m); + + if ( !rc ) + d->arch.p2m = p2m; + else p2m_free_one(p2m); - } - return -ENOMEM; + + return rc; } static void p2m_teardown_hostp2m(struct domain *d) @@ -138,7 +160,7 @@ static void p2m_teardown_hostp2m(struct domain *d) if ( p2m ) { - rangeset_destroy(p2m->logdirty_ranges); + p2m_free_logdirty(p2m); p2m_free_one(p2m); d->arch.p2m = NULL; } @@ -194,6 +216,7 @@ static void p2m_teardown_altp2m(struct domain *d) continue; p2m = d->arch.altp2m_p2m[i]; d->arch.altp2m_p2m[i] = NULL; + p2m_free_logdirty(p2m); p2m_free_one(p2m); } } @@ -2289,10 +2312,7 @@ int p2m_init_altp2m_by_id(struct domain *d, unsigned int idx) altp2m_list_lock(d); if ( d->arch.altp2m_eptp[idx] == mfn_x(INVALID_MFN) ) - { - p2m_init_altp2m_ept(d, idx); - rc = 0; - } + rc = p2m_init_altp2m_ept(d, idx); altp2m_list_unlock(d); return rc; @@ -2310,9 +2330,8 @@ int p2m_init_next_altp2m(struct domain *d, uint16_t *idx) if ( d->arch.altp2m_eptp[i] != mfn_x(INVALID_MFN) ) continue; - p2m_init_altp2m_ept(d, i); + rc = p2m_init_altp2m_ept(d, i); *idx = i; - rc = 0; break; } diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h index b110e16..19730c7 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -598,7 +598,7 @@ void ept_p2m_uninit(struct p2m_domain *p2m); void ept_walk_table(struct domain *d, unsigned long gfn); bool_t ept_handle_misconfig(uint64_t gpa); void setup_ept_dump(void); -void p2m_init_altp2m_ept(struct domain *d, unsigned int i); +int p2m_init_altp2m_ept(struct domain *d, unsigned int i); /* Locate an alternate p2m by its EPTP */ unsigned int p2m_find_altp2m_by_eptp(struct domain *d, uint64_t eptp); diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h index d08c595..aa52212 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -223,7 +223,7 @@ struct p2m_domain { struct rangeset *logdirty_ranges; /* Host p2m: Global log-dirty mode enabled for the domain. */ - bool_t global_logdirty; + bool global_logdirty; /* Host p2m: when this flag is set, don't flush all the nested-p2m * tables on every host-p2m change. The setter of this flag @@ -581,6 +581,9 @@ int p2m_alloc_table(struct p2m_domain *p2m); void p2m_teardown(struct p2m_domain *p2m); void p2m_final_teardown(struct domain *d); +int p2m_init_logdirty(struct p2m_domain *p2m); +void p2m_free_logdirty(struct p2m_domain *p2m); + /* Add a page to a domain's p2m table */ int guest_physmap_add_entry(struct domain *d, gfn_t gfn, mfn_t mfn, unsigned int page_order, -- 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 |