From: jbeulich@novell.com Subject: make pinning of pgd pairs transparent to callers Patch-mainline: obsolete Index: head-2008-12-01/arch/x86/mm/hypervisor.c =================================================================== --- head-2008-12-01.orig/arch/x86/mm/hypervisor.c 2008-12-01 12:13:06.000000000 +0100 +++ head-2008-12-01/arch/x86/mm/hypervisor.c 2008-12-01 12:13:22.000000000 +0100 @@ -517,26 +517,38 @@ void xen_invlpg_mask(cpumask_t *mask, un #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 = pfn_to_mfn(__pa(pgd) >> PAGE_SHIFT); +#ifdef CONFIG_X86_64 + op[1].cmd = op[0].cmd = MMUEXT_PIN_L4_TABLE; + op[1].arg1.mfn = pfn_to_mfn(__pa(__user_pgd(pgd)) >> PAGE_SHIFT); +#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 = pfn_to_mfn(__pa(pgd) >> PAGE_SHIFT); +#ifdef CONFIG_X86_64 + op[1].cmd = MMUEXT_UNPIN_TABLE; + op[1].arg1.mfn = pfn_to_mfn(__pa(__user_pgd(pgd)) >> PAGE_SHIFT); +#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) Index: head-2008-12-01/arch/x86/mm/init_64-xen.c =================================================================== --- head-2008-12-01.orig/arch/x86/mm/init_64-xen.c 2008-12-01 12:13:13.000000000 +0100 +++ head-2008-12-01/arch/x86/mm/init_64-xen.c 2008-12-01 12:13:22.000000000 +0100 @@ -629,10 +629,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); } static void __init extend_init_mapping(unsigned long tables_space) Index: head-2008-12-01/arch/x86/mm/pgtable-xen.c =================================================================== --- head-2008-12-01.orig/arch/x86/mm/pgtable-xen.c 2008-12-01 12:13:16.000000000 +0100 +++ head-2008-12-01/arch/x86/mm/pgtable-xen.c 2008-12-01 12:13:22.000000000 +0100 @@ -347,19 +347,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)); } Index: head-2008-12-01/include/asm-x86/mach-xen/asm/hypervisor.h =================================================================== --- head-2008-12-01.orig/include/asm-x86/mach-xen/asm/hypervisor.h 2008-12-01 12:13:06.000000000 +0100 +++ head-2008-12-01/include/asm-x86/mach-xen/asm/hypervisor.h 2008-12-01 12:13:22.000000000 +0100 @@ -95,8 +95,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);