diff options
Diffstat (limited to 'arch/x86/mm/pgtable.c')
-rw-r--r-- | arch/x86/mm/pgtable.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index ed34f5e35999..5c4ee422590e 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <linux/mm.h> | 1 | #include <linux/mm.h> |
2 | #include <linux/gfp.h> | ||
2 | #include <asm/pgalloc.h> | 3 | #include <asm/pgalloc.h> |
3 | #include <asm/pgtable.h> | 4 | #include <asm/pgtable.h> |
4 | #include <asm/tlb.h> | 5 | #include <asm/tlb.h> |
@@ -6,6 +7,14 @@ | |||
6 | 7 | ||
7 | #define PGALLOC_GFP GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO | 8 | #define PGALLOC_GFP GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO |
8 | 9 | ||
10 | #ifdef CONFIG_HIGHPTE | ||
11 | #define PGALLOC_USER_GFP __GFP_HIGHMEM | ||
12 | #else | ||
13 | #define PGALLOC_USER_GFP 0 | ||
14 | #endif | ||
15 | |||
16 | gfp_t __userpte_alloc_gfp = PGALLOC_GFP | PGALLOC_USER_GFP; | ||
17 | |||
9 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | 18 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) |
10 | { | 19 | { |
11 | return (pte_t *)__get_free_page(PGALLOC_GFP); | 20 | return (pte_t *)__get_free_page(PGALLOC_GFP); |
@@ -15,16 +24,29 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) | |||
15 | { | 24 | { |
16 | struct page *pte; | 25 | struct page *pte; |
17 | 26 | ||
18 | #ifdef CONFIG_HIGHPTE | 27 | pte = alloc_pages(__userpte_alloc_gfp, 0); |
19 | pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0); | ||
20 | #else | ||
21 | pte = alloc_pages(PGALLOC_GFP, 0); | ||
22 | #endif | ||
23 | if (pte) | 28 | if (pte) |
24 | pgtable_page_ctor(pte); | 29 | pgtable_page_ctor(pte); |
25 | return pte; | 30 | return pte; |
26 | } | 31 | } |
27 | 32 | ||
33 | static int __init setup_userpte(char *arg) | ||
34 | { | ||
35 | if (!arg) | ||
36 | return -EINVAL; | ||
37 | |||
38 | /* | ||
39 | * "userpte=nohigh" disables allocation of user pagetables in | ||
40 | * high memory. | ||
41 | */ | ||
42 | if (strcmp(arg, "nohigh") == 0) | ||
43 | __userpte_alloc_gfp &= ~__GFP_HIGHMEM; | ||
44 | else | ||
45 | return -EINVAL; | ||
46 | return 0; | ||
47 | } | ||
48 | early_param("userpte", setup_userpte); | ||
49 | |||
28 | void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte) | 50 | void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte) |
29 | { | 51 | { |
30 | pgtable_page_dtor(pte); | 52 | pgtable_page_dtor(pte); |