aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig5
-rw-r--r--arch/arm/include/asm/pgalloc.h16
-rw-r--r--arch/arm/include/asm/pgtable.h17
-rw-r--r--arch/arm/mm/fault.c1
4 files changed, 31 insertions, 8 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index aef63c8e3d2d..370f47787122 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1054,6 +1054,11 @@ config HIGHMEM
1054 1054
1055 If unsure, say n. 1055 If unsure, say n.
1056 1056
1057config HIGHPTE
1058 bool "Allocate 2nd-level pagetables from highmem"
1059 depends on HIGHMEM
1060 depends on !OUTER_CACHE
1061
1057source "mm/Kconfig" 1062source "mm/Kconfig"
1058 1063
1059config LEDS 1064config LEDS
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index 3dcd64bf1824..b12cc98bbe04 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -36,6 +36,8 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
36#define pgd_alloc(mm) get_pgd_slow(mm) 36#define pgd_alloc(mm) get_pgd_slow(mm)
37#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd) 37#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd)
38 38
39#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
40
39/* 41/*
40 * Allocate one PTE table. 42 * Allocate one PTE table.
41 * 43 *
@@ -57,7 +59,7 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
57{ 59{
58 pte_t *pte; 60 pte_t *pte;
59 61
60 pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); 62 pte = (pte_t *)__get_free_page(PGALLOC_GFP);
61 if (pte) { 63 if (pte) {
62 clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE); 64 clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE);
63 pte += PTRS_PER_PTE; 65 pte += PTRS_PER_PTE;
@@ -71,10 +73,16 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
71{ 73{
72 struct page *pte; 74 struct page *pte;
73 75
74 pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); 76#ifdef CONFIG_HIGHPTE
77 pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0);
78#else
79 pte = alloc_pages(PGALLOC_GFP, 0);
80#endif
75 if (pte) { 81 if (pte) {
76 void *page = page_address(pte); 82 if (!PageHighMem(pte)) {
77 clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE); 83 void *page = page_address(pte);
84 clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
85 }
78 pgtable_page_ctor(pte); 86 pgtable_page_ctor(pte);
79 } 87 }
80 88
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 9655bce3d345..201ccaa11f61 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -262,10 +262,19 @@ extern struct page *empty_zero_page;
262#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) 262#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
263#define pte_page(pte) (pfn_to_page(pte_pfn(pte))) 263#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
264#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) 264#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
265#define pte_offset_map(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) 265
266#define pte_offset_map_nested(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) 266#define pte_offset_map(dir,addr) (__pte_map(dir, KM_PTE0) + __pte_index(addr))
267#define pte_unmap(pte) do { } while (0) 267#define pte_offset_map_nested(dir,addr) (__pte_map(dir, KM_PTE1) + __pte_index(addr))
268#define pte_unmap_nested(pte) do { } while (0) 268#define pte_unmap(pte) __pte_unmap(pte, KM_PTE0)
269#define pte_unmap_nested(pte) __pte_unmap(pte, KM_PTE1)
270
271#ifndef CONFIG_HIGHPTE
272#define __pte_map(dir,km) pmd_page_vaddr(*(dir))
273#define __pte_unmap(pte,km) do { } while (0)
274#else
275#define __pte_map(dir,km) ((pte_t *)kmap_atomic(pmd_page(*(dir)), km) + PTRS_PER_PTE)
276#define __pte_unmap(pte,km) kunmap_atomic((pte - PTRS_PER_PTE), km)
277#endif
269 278
270#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) 279#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
271 280
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 6fdcbb709827..5fa8dea5a371 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -16,6 +16,7 @@
16#include <linux/kprobes.h> 16#include <linux/kprobes.h>
17#include <linux/uaccess.h> 17#include <linux/uaccess.h>
18#include <linux/page-flags.h> 18#include <linux/page-flags.h>
19#include <linux/highmem.h>
19 20
20#include <asm/system.h> 21#include <asm/system.h>
21#include <asm/pgtable.h> 22#include <asm/pgtable.h>