linux/x86: batch hypercalls when pinning address spaces
PATCH 1/1 linux/x86: batch hypercalls when pinning address spaces
Signed-off-by Jan Beulich <[email protected]>
arch/i386/mm/pgtable-xen.c +37 -17
@@ -574,10 +574,13 @@ static void _pin_lock(struct mm_struct * } } -static inline void pgd_walk_set_prot (struct page *page,pgprot_t flags) +#define PIN_BATCH 4 +static DEFINE_PER_CPU(multicall_entry_t[PIN_BATCH], pb_mcl); + +static inline unsigned int pgd_walk_set_prot (struct page *page,pgprot_t flags, +unsigned int cpu,unsigned seq) {unsigned long pfn =page_to_pfn (page); -int rc;if (PageHighMem (page)) {if (pgprot_val (flags) & _PAGE_RW)
@@ -585,12 +588,18 @@ static inline void pgd_walk_set_prot(strelse set_bit (PG_pinned, &page->flags); }else { - rc =HYPERVISOR_update_va_mapping ( - (unsigned long )__va (pfn <<PAGE_SHIFT ), -pfn_pte (pfn, flags),0 ); -if (rc) -BUG (); +MULTI_update_va_mapping (per_cpu (pb_mcl, cpu) + seq, + (unsigned long )__va (pfn <<PAGE_SHIFT ), +pfn_pte (pfn, flags),0 ); +if (unlikely (++seq ==PIN_BATCH )) { +if (unlikely (HYPERVISOR_multicall_check (per_cpu (pb_mcl, cpu), +PIN_BATCH ,NULL ))) +BUG (); + seq =0 ; + } } + +return seq; }static void pgd_walk (pgd_t *pgd_base,pgprot_t flags)
@@ -598,37 +607,48 @@ static void pgd_walk(pgd_t *pgd_base, pgpgd_t *pgd = pgd_base;pud_t *pud;pmd_t *pmd; -int g, u, m, rc; +int g, u, m; +unsigned int cpu, seq;if (xen_feature (XENFEAT_auto_translated_physmap))return ; -for (g =0 ; g <USER_PTRS_PER_PGD ; g++, pgd++) { + cpu =get_cpu (); + +for (g =0 , seq =0 ; g <USER_PTRS_PER_PGD ; g++, pgd++) {if (pgd_none (*pgd))continue ; pud =pud_offset (pgd,0 );if (PTRS_PER_PUD >1 )/* not folded */ -pgd_walk_set_prot (virt_to_page (pud),flags); + seq =pgd_walk_set_prot (virt_to_page (pud),flags,cpu,seq);for (u =0 ; u <PTRS_PER_PUD ; u++, pud++) {if (pud_none (*pud))continue ; pmd =pmd_offset (pud,0 );if (PTRS_PER_PMD >1 )/* not folded */ -pgd_walk_set_prot (virt_to_page (pmd),flags); + seq =pgd_walk_set_prot (virt_to_page (pmd),flags,cpu,seq);for (m =0 ; m <PTRS_PER_PMD ; m++, pmd++) {if (pmd_none (*pmd))continue ; -pgd_walk_set_prot (pmd_page (*pmd),flags); + seq =pgd_walk_set_prot (pmd_page (*pmd),flags,cpu,seq); } } } - rc =HYPERVISOR_update_va_mapping ( - (unsigned long )pgd_base, -pfn_pte (virt_to_phys (pgd_base)>>PAGE_SHIFT , flags), -UVMF_TLB_FLUSH ); -if (rc) +if (likely (seq !=0 )) { +MULTI_update_va_mapping (per_cpu (pb_mcl, cpu) + seq, + (unsigned long )pgd_base, +pfn_pte (virt_to_phys (pgd_base)>>PAGE_SHIFT , flags), +UVMF_TLB_FLUSH ); +if (unlikely (HYPERVISOR_multicall_check (per_cpu (pb_mcl, cpu), + seq +1 ,NULL ))) +BUG (); + }else if (HYPERVISOR_update_va_mapping ((unsigned long )pgd_base, +pfn_pte (virt_to_phys (pgd_base)>>PAGE_SHIFT , flags), +UVMF_TLB_FLUSH ))BUG (); + +put_cpu (); }static void __pgd_pin (pgd_t *pgd)
arch/x86_64/mm/pageattr-xen.c +41 -30
126 lines not on this page · raw message