pgd.c (94bd217e2d683719ab21a4ac117d8a1b91cbedc9) | pgd.c (da02877987e6e173ebba137d4e1e155e1f1151cd) |
---|---|
1/* 2 * linux/arch/arm/mm/pgd.c 3 * 4 * Copyright (C) 1998-2005 Russell King 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10#include <linux/mm.h> 11#include <linux/gfp.h> 12#include <linux/highmem.h> | 1/* 2 * linux/arch/arm/mm/pgd.c 3 * 4 * Copyright (C) 1998-2005 Russell King 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10#include <linux/mm.h> 11#include <linux/gfp.h> 12#include <linux/highmem.h> |
13#include <linux/slab.h> |
|
13 14#include <asm/pgalloc.h> 15#include <asm/page.h> 16#include <asm/tlbflush.h> 17 18#include "mm.h" 19 | 14 15#include <asm/pgalloc.h> 16#include <asm/page.h> 17#include <asm/tlbflush.h> 18 19#include "mm.h" 20 |
21#ifdef CONFIG_ARM_LPAE 22#define __pgd_alloc() kmalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL) 23#define __pgd_free(pgd) kfree(pgd) 24#else 25#define __pgd_alloc() (pgd_t *)__get_free_pages(GFP_KERNEL, 2) 26#define __pgd_free(pgd) free_pages((unsigned long)pgd, 2) 27#endif 28 |
|
20/* 21 * need to get a 16k page for level 1 22 */ 23pgd_t *pgd_alloc(struct mm_struct *mm) 24{ 25 pgd_t *new_pgd, *init_pgd; 26 pud_t *new_pud, *init_pud; 27 pmd_t *new_pmd, *init_pmd; 28 pte_t *new_pte, *init_pte; 29 | 29/* 30 * need to get a 16k page for level 1 31 */ 32pgd_t *pgd_alloc(struct mm_struct *mm) 33{ 34 pgd_t *new_pgd, *init_pgd; 35 pud_t *new_pud, *init_pud; 36 pmd_t *new_pmd, *init_pmd; 37 pte_t *new_pte, *init_pte; 38 |
30 new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2); | 39 new_pgd = __pgd_alloc(); |
31 if (!new_pgd) 32 goto no_pgd; 33 34 memset(new_pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); 35 36 /* 37 * Copy over the kernel and IO PGD entries 38 */ 39 init_pgd = pgd_offset_k(0); 40 memcpy(new_pgd + USER_PTRS_PER_PGD, init_pgd + USER_PTRS_PER_PGD, 41 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 42 43 clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); 44 | 40 if (!new_pgd) 41 goto no_pgd; 42 43 memset(new_pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); 44 45 /* 46 * Copy over the kernel and IO PGD entries 47 */ 48 init_pgd = pgd_offset_k(0); 49 memcpy(new_pgd + USER_PTRS_PER_PGD, init_pgd + USER_PTRS_PER_PGD, 50 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 51 52 clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); 53 |
54#ifdef CONFIG_ARM_LPAE 55 /* 56 * Allocate PMD table for modules and pkmap mappings. 57 */ 58 new_pud = pud_alloc(mm, new_pgd + pgd_index(MODULES_VADDR), 59 MODULES_VADDR); 60 if (!new_pud) 61 goto no_pud; 62 63 new_pmd = pmd_alloc(mm, new_pud, 0); 64 if (!new_pmd) 65 goto no_pmd; 66#endif 67 |
|
45 if (!vectors_high()) { 46 /* 47 * On ARM, first page must always be allocated since it | 68 if (!vectors_high()) { 69 /* 70 * On ARM, first page must always be allocated since it |
48 * contains the machine vectors. | 71 * contains the machine vectors. The vectors are always high 72 * with LPAE. |
49 */ 50 new_pud = pud_alloc(mm, new_pgd, 0); 51 if (!new_pud) 52 goto no_pud; 53 54 new_pmd = pmd_alloc(mm, new_pud, 0); 55 if (!new_pmd) 56 goto no_pmd; --- 12 unchanged lines hidden (view full) --- 69 70 return new_pgd; 71 72no_pte: 73 pmd_free(mm, new_pmd); 74no_pmd: 75 pud_free(mm, new_pud); 76no_pud: | 73 */ 74 new_pud = pud_alloc(mm, new_pgd, 0); 75 if (!new_pud) 76 goto no_pud; 77 78 new_pmd = pmd_alloc(mm, new_pud, 0); 79 if (!new_pmd) 80 goto no_pmd; --- 12 unchanged lines hidden (view full) --- 93 94 return new_pgd; 95 96no_pte: 97 pmd_free(mm, new_pmd); 98no_pmd: 99 pud_free(mm, new_pud); 100no_pud: |
77 free_pages((unsigned long)new_pgd, 2); | 101 __pgd_free(new_pgd); |
78no_pgd: 79 return NULL; 80} 81 82void pgd_free(struct mm_struct *mm, pgd_t *pgd_base) 83{ 84 pgd_t *pgd; 85 pud_t *pud; --- 20 unchanged lines hidden (view full) --- 106 pte_free(mm, pte); 107no_pmd: 108 pud_clear(pud); 109 pmd_free(mm, pmd); 110no_pud: 111 pgd_clear(pgd); 112 pud_free(mm, pud); 113no_pgd: | 102no_pgd: 103 return NULL; 104} 105 106void pgd_free(struct mm_struct *mm, pgd_t *pgd_base) 107{ 108 pgd_t *pgd; 109 pud_t *pud; --- 20 unchanged lines hidden (view full) --- 130 pte_free(mm, pte); 131no_pmd: 132 pud_clear(pud); 133 pmd_free(mm, pmd); 134no_pud: 135 pgd_clear(pgd); 136 pud_free(mm, pud); 137no_pgd: |
114 free_pages((unsigned long) pgd_base, 2); | 138#ifdef CONFIG_ARM_LPAE 139 /* 140 * Free modules/pkmap or identity pmd tables. 141 */ 142 for (pgd = pgd_base; pgd < pgd_base + PTRS_PER_PGD; pgd++) { 143 if (pgd_none_or_clear_bad(pgd)) 144 continue; 145 if (pgd_val(*pgd) & L_PGD_SWAPPER) 146 continue; 147 pud = pud_offset(pgd, 0); 148 if (pud_none_or_clear_bad(pud)) 149 continue; 150 pmd = pmd_offset(pud, 0); 151 pud_clear(pud); 152 pmd_free(mm, pmd); 153 pgd_clear(pgd); 154 pud_free(mm, pud); 155 } 156#endif 157 __pgd_free(pgd_base); |
115} | 158} |