From 9f7105d6ac9eb99fa031682b24570596334d68c9 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 12 Jan 2007 10:28:54 +0000 Subject: [PATCH] linux/i386: allow CONFIG_HIGHPTE on i386 While, as discussed, the performance impact of this option is certainly higher than on native Linux, the option should not be entirely disallowed if people want to sacrifice performance for less lowmem pressure. Signed-off-by: Jan Beulich --- linux-2.6-xen-sparse/arch/i386/Kconfig | 2 +- .../arch/i386/mm/highmem-xen.c | 1 + .../arch/i386/mm/pgtable-xen.c | 28 +++++++++++++++---- .../include/asm-i386/mach-xen/asm/pgalloc.h | 2 +- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/i386/Kconfig b/linux-2.6-xen-sparse/arch/i386/Kconfig index 8c712269d0..4c0d2f8c80 100644 --- a/linux-2.6-xen-sparse/arch/i386/Kconfig +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig @@ -594,7 +594,7 @@ config HAVE_ARCH_EARLY_PFN_TO_NID config HIGHPTE bool "Allocate 3rd-level pagetables from highmem" - depends on (HIGHMEM4G || HIGHMEM64G) && !X86_XEN + depends on HIGHMEM4G || HIGHMEM64G help The VM uses one page table entry for each page of physical memory. For systems with a lot of RAM, this can be wasteful of precious diff --git a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c index 23f0e1b2e9..ee7deae2a7 100644 --- a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c @@ -129,5 +129,6 @@ struct page *kmap_atomic_to_page(void *ptr) EXPORT_SYMBOL(kmap); EXPORT_SYMBOL(kunmap); EXPORT_SYMBOL(kmap_atomic); +EXPORT_SYMBOL(kmap_atomic_pte); EXPORT_SYMBOL(kunmap_atomic); EXPORT_SYMBOL(kmap_atomic_to_page); diff --git a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c index 0ff01f52f8..8f2239b427 100644 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c @@ -238,23 +238,41 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) #ifdef CONFIG_HIGHPTE pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0); + if (pte && PageHighMem(pte)) { + struct mmuext_op op; + + kmap_flush_unused(); + op.cmd = MMUEXT_PIN_L1_TABLE; + op.arg1.mfn = pfn_to_mfn(page_to_pfn(pte)); + BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); + } #else pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); +#endif if (pte) { SetPageForeign(pte, pte_free); set_page_count(pte, 1); } -#endif return pte; } void pte_free(struct page *pte) { - unsigned long va = (unsigned long)__va(page_to_pfn(pte)<