[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/2] x86/mm: factor out the code for shattering an l2 PTE
map_pages_to_xen and modify_xen_mappings are performing almost exactly the same operations when shattering an l2 PTE, the only difference being whether we want to flush. Signed-off-by: Hongyan Xia <hongyxia@xxxxxxxxxx> --- xen/arch/x86/mm.c | 81 ++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 43 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 42aaaa1083..65f0758a6f 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -5151,6 +5151,41 @@ l1_pgentry_t *virt_to_xen_l1e(unsigned long v) flush_area_local((const void *)v, f) : \ flush_area_all((const void *)v, f)) +/* Shatter an l2 entry and populate l1. If virt is passed in, also do flush. */ +static void shatter_l2e(l2_pgentry_t *pl2e, l1_pgentry_t *l1t, + unsigned long virt, bool locking) +{ + unsigned int i; + l2_pgentry_t ol2e = *pl2e; + + for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) + l1e_write(l1t + i, + l1e_from_pfn(l2e_get_pfn(ol2e) + i, + lNf_to_l1f(l2e_get_flags(ol2e)))); + if ( locking ) + spin_lock(&map_pgdir_lock); + if ( (l2e_get_flags(ol2e) & _PAGE_PRESENT) && + (l2e_get_flags(ol2e) & _PAGE_PSE) ) + { + l2e_write_atomic(pl2e, l2e_from_mfn(virt_to_mfn(l1t), + __PAGE_HYPERVISOR)); + l1t = NULL; + } + if ( locking ) + spin_unlock(&map_pgdir_lock); + if ( virt ) + { + unsigned int flush_flags = + FLUSH_TLB | FLUSH_ORDER(PAGETABLE_ORDER); + + if ( l2e_get_flags(ol2e) & _PAGE_GLOBAL ) + flush_flags |= FLUSH_TLB_GLOBAL; + flush_area(virt, flush_flags); + } + if ( l1t ) + free_xen_pagetable(l1t); +} + /* Shatter an l3 entry and populate l2. If virt is passed in, also do flush. */ static void shatter_l3e(l3_pgentry_t *pl3e, l2_pgentry_t *l2t, unsigned long virt, bool locking) @@ -5357,9 +5392,6 @@ int map_pages_to_xen( } else if ( l2e_get_flags(*pl2e) & _PAGE_PSE ) { - unsigned int flush_flags = - FLUSH_TLB | FLUSH_ORDER(PAGETABLE_ORDER); - /* Skip this PTE if there is no change. */ if ( (((l2e_get_pfn(*pl2e) & ~(L1_PAGETABLE_ENTRIES - 1)) + l1_table_offset(virt)) == mfn_x(mfn)) && @@ -5381,29 +5413,8 @@ int map_pages_to_xen( pl1e = alloc_xen_pagetable(); if ( pl1e == NULL ) return -ENOMEM; - - for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) - l1e_write(&pl1e[i], - l1e_from_pfn(l2e_get_pfn(*pl2e) + i, - lNf_to_l1f(l2e_get_flags(*pl2e)))); - - if ( l2e_get_flags(*pl2e) & _PAGE_GLOBAL ) - flush_flags |= FLUSH_TLB_GLOBAL; - - if ( locking ) - spin_lock(&map_pgdir_lock); - if ( (l2e_get_flags(*pl2e) & _PAGE_PRESENT) && - (l2e_get_flags(*pl2e) & _PAGE_PSE) ) - { - l2e_write_atomic(pl2e, l2e_from_mfn(virt_to_mfn(pl1e), - __PAGE_HYPERVISOR)); - pl1e = NULL; - } - if ( locking ) - spin_unlock(&map_pgdir_lock); - flush_area(virt, flush_flags); - if ( pl1e ) - free_xen_pagetable(pl1e); + /* Pass virt to indicate we need to flush. */ + shatter_l2e(pl2e, pl1e, virt, locking); } pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(virt); @@ -5631,23 +5642,7 @@ int modify_xen_mappings(unsigned long s, unsigned long e, unsigned int nf) pl1e = alloc_xen_pagetable(); if ( !pl1e ) return -ENOMEM; - for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) - l1e_write(&pl1e[i], - l1e_from_pfn(l2e_get_pfn(*pl2e) + i, - l2e_get_flags(*pl2e) & ~_PAGE_PSE)); - if ( locking ) - spin_lock(&map_pgdir_lock); - if ( (l2e_get_flags(*pl2e) & _PAGE_PRESENT) && - (l2e_get_flags(*pl2e) & _PAGE_PSE) ) - { - l2e_write_atomic(pl2e, l2e_from_mfn(virt_to_mfn(pl1e), - __PAGE_HYPERVISOR)); - pl1e = NULL; - } - if ( locking ) - spin_unlock(&map_pgdir_lock); - if ( pl1e ) - free_xen_pagetable(pl1e); + shatter_l2e(pl2e, pl1e, 0, locking); } } else -- 2.17.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |