From: jbeulich@novell.com Subject: make pinning of pgd pairs transparent to callers Patch-mainline: obsolete --- head-2010-04-15.orig/arch/x86/include/mach-xen/asm/hypervisor.h 2010-03-25 14:41:15.000000000 +0100 +++ head-2010-04-15/arch/x86/include/mach-xen/asm/hypervisor.h 2010-03-25 14:45:56.000000000 +0100 @@ -112,8 +112,8 @@ void xen_l1_entry_update(pte_t *ptr, pte void xen_l2_entry_update(pmd_t *ptr, pmd_t val); void xen_l3_entry_update(pud_t *ptr, pud_t val); /* x86_64/PAE */ void xen_l4_entry_update(pgd_t *ptr, int user, pgd_t val); /* x86_64 only */ -void xen_pgd_pin(unsigned long ptr); -void xen_pgd_unpin(unsigned long ptr); +void xen_pgd_pin(pgd_t *); +void xen_pgd_unpin(pgd_t *); void xen_init_pgd_pin(void); --- head-2010-04-15.orig/arch/x86/mm/hypervisor.c 2010-03-25 14:41:15.000000000 +0100 +++ head-2010-04-15/arch/x86/mm/hypervisor.c 2010-03-25 17:55:14.000000000 +0100 @@ -623,26 +623,38 @@ EXPORT_SYMBOL_GPL(xen_invlpg_mask); #endif /* CONFIG_SMP */ -void xen_pgd_pin(unsigned long ptr) -{ - struct mmuext_op op; #ifdef CONFIG_X86_64 - op.cmd = MMUEXT_PIN_L4_TABLE; -#elif defined(CONFIG_X86_PAE) - op.cmd = MMUEXT_PIN_L3_TABLE; +#define NR_PGD_PIN_OPS 2 #else - op.cmd = MMUEXT_PIN_L2_TABLE; +#define NR_PGD_PIN_OPS 1 #endif - op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT); - BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); + +void xen_pgd_pin(pgd_t *pgd) +{ + struct mmuext_op op[NR_PGD_PIN_OPS]; + + op[0].cmd = MMUEXT_PIN_L3_TABLE; + op[0].arg1.mfn = virt_to_mfn(pgd); +#ifdef CONFIG_X86_64 + op[1].cmd = op[0].cmd = MMUEXT_PIN_L4_TABLE; + op[1].arg1.mfn = virt_to_mfn(__user_pgd(pgd)); +#endif + if (HYPERVISOR_mmuext_op(op, NR_PGD_PIN_OPS, NULL, DOMID_SELF) < 0) + BUG(); } -void xen_pgd_unpin(unsigned long ptr) +void xen_pgd_unpin(pgd_t *pgd) { - struct mmuext_op op; - op.cmd = MMUEXT_UNPIN_TABLE; - op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT); - BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); + struct mmuext_op op[NR_PGD_PIN_OPS]; + + op[0].cmd = MMUEXT_UNPIN_TABLE; + op[0].arg1.mfn = virt_to_mfn(pgd); +#ifdef CONFIG_X86_64 + op[1].cmd = MMUEXT_UNPIN_TABLE; + op[1].arg1.mfn = virt_to_mfn(__user_pgd(pgd)); +#endif + if (HYPERVISOR_mmuext_op(op, NR_PGD_PIN_OPS, NULL, DOMID_SELF) < 0) + BUG(); } void xen_set_ldt(const void *ptr, unsigned int ents) --- head-2010-04-15.orig/arch/x86/mm/init_64-xen.c 2010-04-15 11:48:38.000000000 +0200 +++ head-2010-04-15/arch/x86/mm/init_64-xen.c 2010-04-15 11:49:06.000000000 +0200 @@ -753,10 +753,8 @@ void __init xen_init_pt(void) early_make_page_readonly(level1_fixmap_pgt, XENFEAT_writable_page_tables); - if (!xen_feature(XENFEAT_writable_page_tables)) { - xen_pgd_pin(__pa_symbol(init_level4_pgt)); - xen_pgd_pin(__pa_symbol(__user_pgd(init_level4_pgt))); - } + if (!xen_feature(XENFEAT_writable_page_tables)) + xen_pgd_pin(init_level4_pgt); } void __init xen_finish_init_mapping(void) --- head-2010-04-15.orig/arch/x86/mm/pgtable-xen.c 2010-04-15 11:48:29.000000000 +0200 +++ head-2010-04-15/arch/x86/mm/pgtable-xen.c 2010-04-15 11:49:08.000000000 +0200 @@ -368,19 +368,13 @@ static void __pgd_pin(pgd_t *pgd) { pgd_walk(pgd, PAGE_KERNEL_RO); kmap_flush_unused(); - xen_pgd_pin(__pa(pgd)); /* kernel */ -#ifdef CONFIG_X86_64 - xen_pgd_pin(__pa(__user_pgd(pgd))); /* user */ -#endif + xen_pgd_pin(pgd); SetPagePinned(virt_to_page(pgd)); } static void __pgd_unpin(pgd_t *pgd) { - xen_pgd_unpin(__pa(pgd)); -#ifdef CONFIG_X86_64 - xen_pgd_unpin(__pa(__user_pgd(pgd))); -#endif + xen_pgd_unpin(pgd); pgd_walk(pgd, PAGE_KERNEL); ClearPagePinned(virt_to_page(pgd)); }