1 /* 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3 * Licensed under the GPL 4 */ 5 6 #include <linux/stddef.h> 7 #include <linux/module.h> 8 #include <linux/bootmem.h> 9 #include <linux/highmem.h> 10 #include <linux/mm.h> 11 #include <linux/swap.h> 12 #include <linux/slab.h> 13 #include <asm/fixmap.h> 14 #include <asm/page.h> 15 #include <as-layout.h> 16 #include <init.h> 17 #include <kern.h> 18 #include <kern_util.h> 19 #include <mem_user.h> 20 #include <os.h> 21 22 /* allocated in paging_init, zeroed in mem_init, and unchanged thereafter */ 23 unsigned long *empty_zero_page = NULL; 24 EXPORT_SYMBOL(empty_zero_page); 25 /* allocated in paging_init and unchanged thereafter */ 26 static unsigned long *empty_bad_page = NULL; 27 28 /* 29 * Initialized during boot, and readonly for initializing page tables 30 * afterwards 31 */ 32 pgd_t swapper_pg_dir[PTRS_PER_PGD]; 33 34 /* Initialized at boot time, and readonly after that */ 35 unsigned long long highmem; 36 int kmalloc_ok = 0; 37 38 /* Used during early boot */ 39 static unsigned long brk_end; 40 41 #ifdef CONFIG_HIGHMEM 42 static void setup_highmem(unsigned long highmem_start, 43 unsigned long highmem_len) 44 { 45 unsigned long highmem_pfn; 46 int i; 47 48 highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT; 49 for (i = 0; i < highmem_len >> PAGE_SHIFT; i++) 50 free_highmem_page(&mem_map[highmem_pfn + i]); 51 } 52 #endif 53 54 void __init mem_init(void) 55 { 56 /* clear the zero-page */ 57 memset(empty_zero_page, 0, PAGE_SIZE); 58 59 /* Map in the area just after the brk now that kmalloc is about 60 * to be turned on. 61 */ 62 brk_end = (unsigned long) UML_ROUND_UP(sbrk(0)); 63 map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0); 64 free_bootmem(__pa(brk_end), uml_reserved - brk_end); 65 uml_reserved = brk_end; 66 67 /* this will put all low memory onto the freelists */ 68 free_all_bootmem(); 69 max_low_pfn = totalram_pages; 70 #ifdef CONFIG_HIGHMEM 71 setup_highmem(end_iomem, highmem); 72 #endif 73 max_pfn = totalram_pages; 74 mem_init_print_info(NULL); 75 kmalloc_ok = 1; 76 } 77 78 /* 79 * Create a page table and place a pointer to it in a middle page 80 * directory entry. 81 */ 82 static void __init one_page_table_init(pmd_t *pmd) 83 { 84 if (pmd_none(*pmd)) { 85 pte_t *pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); 86 set_pmd(pmd, __pmd(_KERNPG_TABLE + 87 (unsigned long) __pa(pte))); 88 if (pte != pte_offset_kernel(pmd, 0)) 89 BUG(); 90 } 91 } 92 93 static void __init one_md_table_init(pud_t *pud) 94 { 95 #ifdef CONFIG_3_LEVEL_PGTABLES 96 pmd_t *pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); 97 set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table))); 98 if (pmd_table != pmd_offset(pud, 0)) 99 BUG(); 100 #endif 101 } 102 103 static void __init fixrange_init(unsigned long start, unsigned long end, 104 pgd_t *pgd_base) 105 { 106 pgd_t *pgd; 107 pud_t *pud; 108 pmd_t *pmd; 109 int i, j; 110 unsigned long vaddr; 111 112 vaddr = start; 113 i = pgd_index(vaddr); 114 j = pmd_index(vaddr); 115 pgd = pgd_base + i; 116 117 for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { 118 pud = pud_offset(pgd, vaddr); 119 if (pud_none(*pud)) 120 one_md_table_init(pud); 121 pmd = pmd_offset(pud, vaddr); 122 for (; (j < PTRS_PER_PMD) && (vaddr < end); pmd++, j++) { 123 one_page_table_init(pmd); 124 vaddr += PMD_SIZE; 125 } 126 j = 0; 127 } 128 } 129 130 #ifdef CONFIG_HIGHMEM 131 pte_t *kmap_pte; 132 pgprot_t kmap_prot; 133 134 #define kmap_get_fixmap_pte(vaddr) \ 135 pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)),\ 136 (vaddr)), (vaddr)) 137 138 static void __init kmap_init(void) 139 { 140 unsigned long kmap_vstart; 141 142 /* cache the first kmap pte */ 143 kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); 144 kmap_pte = kmap_get_fixmap_pte(kmap_vstart); 145 146 kmap_prot = PAGE_KERNEL; 147 } 148 149 static void __init init_highmem(void) 150 { 151 pgd_t *pgd; 152 pud_t *pud; 153 pmd_t *pmd; 154 pte_t *pte; 155 unsigned long vaddr; 156 157 /* 158 * Permanent kmaps: 159 */ 160 vaddr = PKMAP_BASE; 161 fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, swapper_pg_dir); 162 163 pgd = swapper_pg_dir + pgd_index(vaddr); 164 pud = pud_offset(pgd, vaddr); 165 pmd = pmd_offset(pud, vaddr); 166 pte = pte_offset_kernel(pmd, vaddr); 167 pkmap_page_table = pte; 168 169 kmap_init(); 170 } 171 #endif /* CONFIG_HIGHMEM */ 172 173 static void __init fixaddr_user_init( void) 174 { 175 #ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA 176 long size = FIXADDR_USER_END - FIXADDR_USER_START; 177 pgd_t *pgd; 178 pud_t *pud; 179 pmd_t *pmd; 180 pte_t *pte; 181 phys_t p; 182 unsigned long v, vaddr = FIXADDR_USER_START; 183 184 if (!size) 185 return; 186 187 fixrange_init( FIXADDR_USER_START, FIXADDR_USER_END, swapper_pg_dir); 188 v = (unsigned long) alloc_bootmem_low_pages(size); 189 memcpy((void *) v , (void *) FIXADDR_USER_START, size); 190 p = __pa(v); 191 for ( ; size > 0; size -= PAGE_SIZE, vaddr += PAGE_SIZE, 192 p += PAGE_SIZE) { 193 pgd = swapper_pg_dir + pgd_index(vaddr); 194 pud = pud_offset(pgd, vaddr); 195 pmd = pmd_offset(pud, vaddr); 196 pte = pte_offset_kernel(pmd, vaddr); 197 pte_set_val(*pte, p, PAGE_READONLY); 198 } 199 #endif 200 } 201 202 void __init paging_init(void) 203 { 204 unsigned long zones_size[MAX_NR_ZONES], vaddr; 205 int i; 206 207 empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE); 208 empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE); 209 for (i = 0; i < ARRAY_SIZE(zones_size); i++) 210 zones_size[i] = 0; 211 212 zones_size[ZONE_NORMAL] = (end_iomem >> PAGE_SHIFT) - 213 (uml_physmem >> PAGE_SHIFT); 214 #ifdef CONFIG_HIGHMEM 215 zones_size[ZONE_HIGHMEM] = highmem >> PAGE_SHIFT; 216 #endif 217 free_area_init(zones_size); 218 219 /* 220 * Fixed mappings, only the page table structure has to be 221 * created - mappings will be set by set_fixmap(): 222 */ 223 vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; 224 fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir); 225 226 fixaddr_user_init(); 227 228 #ifdef CONFIG_HIGHMEM 229 init_highmem(); 230 #endif 231 } 232 233 /* 234 * This can't do anything because nothing in the kernel image can be freed 235 * since it's not in kernel physical memory. 236 */ 237 238 void free_initmem(void) 239 { 240 } 241 242 #ifdef CONFIG_BLK_DEV_INITRD 243 void free_initrd_mem(unsigned long start, unsigned long end) 244 { 245 free_reserved_area((void *)start, (void *)end, -1, "initrd"); 246 } 247 #endif 248 249 /* Allocate and free page tables. */ 250 251 pgd_t *pgd_alloc(struct mm_struct *mm) 252 { 253 pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL); 254 255 if (pgd) { 256 memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); 257 memcpy(pgd + USER_PTRS_PER_PGD, 258 swapper_pg_dir + USER_PTRS_PER_PGD, 259 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 260 } 261 return pgd; 262 } 263 264 void pgd_free(struct mm_struct *mm, pgd_t *pgd) 265 { 266 free_page((unsigned long) pgd); 267 } 268 269 pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) 270 { 271 pte_t *pte; 272 273 pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); 274 return pte; 275 } 276 277 pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) 278 { 279 struct page *pte; 280 281 pte = alloc_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); 282 if (!pte) 283 return NULL; 284 if (!pgtable_page_ctor(pte)) { 285 __free_page(pte); 286 return NULL; 287 } 288 return pte; 289 } 290 291 #ifdef CONFIG_3_LEVEL_PGTABLES 292 pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) 293 { 294 pmd_t *pmd = (pmd_t *) __get_free_page(GFP_KERNEL); 295 296 if (pmd) 297 memset(pmd, 0, PAGE_SIZE); 298 299 return pmd; 300 } 301 #endif 302 303 void *uml_kmalloc(int size, int flags) 304 { 305 return kmalloc(size, flags); 306 } 307