diff options
Diffstat (limited to 'arch/i386/mm')
-rw-r--r-- | arch/i386/mm/boot_ioremap.c | 7 | ||||
-rw-r--r-- | arch/i386/mm/discontig.c | 33 | ||||
-rw-r--r-- | arch/i386/mm/init.c | 44 | ||||
-rw-r--r-- | arch/i386/mm/pgtable.c | 30 |
4 files changed, 100 insertions, 14 deletions
diff --git a/arch/i386/mm/boot_ioremap.c b/arch/i386/mm/boot_ioremap.c index 5d44f4f5ff59..4de11f508c3a 100644 --- a/arch/i386/mm/boot_ioremap.c +++ b/arch/i386/mm/boot_ioremap.c | |||
@@ -29,8 +29,11 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #define BOOT_PTE_PTRS (PTRS_PER_PTE*2) | 31 | #define BOOT_PTE_PTRS (PTRS_PER_PTE*2) |
32 | #define boot_pte_index(address) \ | 32 | |
33 | (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1)) | 33 | static unsigned long boot_pte_index(unsigned long vaddr) |
34 | { | ||
35 | return __pa(vaddr) >> PAGE_SHIFT; | ||
36 | } | ||
34 | 37 | ||
35 | static inline boot_pte_t* boot_vaddr_to_pte(void *address) | 38 | static inline boot_pte_t* boot_vaddr_to_pte(void *address) |
36 | { | 39 | { |
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c index 7c392dc553b8..fb5d8b747de4 100644 --- a/arch/i386/mm/discontig.c +++ b/arch/i386/mm/discontig.c | |||
@@ -117,7 +117,8 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags); | |||
117 | 117 | ||
118 | void *node_remap_end_vaddr[MAX_NUMNODES]; | 118 | void *node_remap_end_vaddr[MAX_NUMNODES]; |
119 | void *node_remap_alloc_vaddr[MAX_NUMNODES]; | 119 | void *node_remap_alloc_vaddr[MAX_NUMNODES]; |
120 | 120 | static unsigned long kva_start_pfn; | |
121 | static unsigned long kva_pages; | ||
121 | /* | 122 | /* |
122 | * FLAT - support for basic PC memory model with discontig enabled, essentially | 123 | * FLAT - support for basic PC memory model with discontig enabled, essentially |
123 | * a single node with all available processors in it with a flat | 124 | * a single node with all available processors in it with a flat |
@@ -286,7 +287,6 @@ unsigned long __init setup_memory(void) | |||
286 | { | 287 | { |
287 | int nid; | 288 | int nid; |
288 | unsigned long system_start_pfn, system_max_low_pfn; | 289 | unsigned long system_start_pfn, system_max_low_pfn; |
289 | unsigned long reserve_pages; | ||
290 | 290 | ||
291 | /* | 291 | /* |
292 | * When mapping a NUMA machine we allocate the node_mem_map arrays | 292 | * When mapping a NUMA machine we allocate the node_mem_map arrays |
@@ -298,14 +298,23 @@ unsigned long __init setup_memory(void) | |||
298 | find_max_pfn(); | 298 | find_max_pfn(); |
299 | get_memcfg_numa(); | 299 | get_memcfg_numa(); |
300 | 300 | ||
301 | reserve_pages = calculate_numa_remap_pages(); | 301 | kva_pages = calculate_numa_remap_pages(); |
302 | 302 | ||
303 | /* partially used pages are not usable - thus round upwards */ | 303 | /* partially used pages are not usable - thus round upwards */ |
304 | system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end); | 304 | system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end); |
305 | 305 | ||
306 | system_max_low_pfn = max_low_pfn = find_max_low_pfn() - reserve_pages; | 306 | kva_start_pfn = find_max_low_pfn() - kva_pages; |
307 | printk("reserve_pages = %ld find_max_low_pfn() ~ %ld\n", | 307 | |
308 | reserve_pages, max_low_pfn + reserve_pages); | 308 | #ifdef CONFIG_BLK_DEV_INITRD |
309 | /* Numa kva area is below the initrd */ | ||
310 | if (LOADER_TYPE && INITRD_START) | ||
311 | kva_start_pfn = PFN_DOWN(INITRD_START) - kva_pages; | ||
312 | #endif | ||
313 | kva_start_pfn -= kva_start_pfn & (PTRS_PER_PTE-1); | ||
314 | |||
315 | system_max_low_pfn = max_low_pfn = find_max_low_pfn(); | ||
316 | printk("kva_start_pfn ~ %ld find_max_low_pfn() ~ %ld\n", | ||
317 | kva_start_pfn, max_low_pfn); | ||
309 | printk("max_pfn = %ld\n", max_pfn); | 318 | printk("max_pfn = %ld\n", max_pfn); |
310 | #ifdef CONFIG_HIGHMEM | 319 | #ifdef CONFIG_HIGHMEM |
311 | highstart_pfn = highend_pfn = max_pfn; | 320 | highstart_pfn = highend_pfn = max_pfn; |
@@ -323,7 +332,7 @@ unsigned long __init setup_memory(void) | |||
323 | (ulong) pfn_to_kaddr(max_low_pfn)); | 332 | (ulong) pfn_to_kaddr(max_low_pfn)); |
324 | for_each_online_node(nid) { | 333 | for_each_online_node(nid) { |
325 | node_remap_start_vaddr[nid] = pfn_to_kaddr( | 334 | node_remap_start_vaddr[nid] = pfn_to_kaddr( |
326 | highstart_pfn + node_remap_offset[nid]); | 335 | kva_start_pfn + node_remap_offset[nid]); |
327 | /* Init the node remap allocator */ | 336 | /* Init the node remap allocator */ |
328 | node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] + | 337 | node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] + |
329 | (node_remap_size[nid] * PAGE_SIZE); | 338 | (node_remap_size[nid] * PAGE_SIZE); |
@@ -338,7 +347,6 @@ unsigned long __init setup_memory(void) | |||
338 | } | 347 | } |
339 | printk("High memory starts at vaddr %08lx\n", | 348 | printk("High memory starts at vaddr %08lx\n", |
340 | (ulong) pfn_to_kaddr(highstart_pfn)); | 349 | (ulong) pfn_to_kaddr(highstart_pfn)); |
341 | vmalloc_earlyreserve = reserve_pages * PAGE_SIZE; | ||
342 | for_each_online_node(nid) | 350 | for_each_online_node(nid) |
343 | find_max_pfn_node(nid); | 351 | find_max_pfn_node(nid); |
344 | 352 | ||
@@ -348,13 +356,18 @@ unsigned long __init setup_memory(void) | |||
348 | return max_low_pfn; | 356 | return max_low_pfn; |
349 | } | 357 | } |
350 | 358 | ||
359 | void __init numa_kva_reserve(void) | ||
360 | { | ||
361 | reserve_bootmem(PFN_PHYS(kva_start_pfn),PFN_PHYS(kva_pages)); | ||
362 | } | ||
363 | |||
351 | void __init zone_sizes_init(void) | 364 | void __init zone_sizes_init(void) |
352 | { | 365 | { |
353 | int nid; | 366 | int nid; |
354 | 367 | ||
355 | 368 | ||
356 | for_each_online_node(nid) { | 369 | for_each_online_node(nid) { |
357 | unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; | 370 | unsigned long zones_size[MAX_NR_ZONES] = {0, }; |
358 | unsigned long *zholes_size; | 371 | unsigned long *zholes_size; |
359 | unsigned int max_dma; | 372 | unsigned int max_dma; |
360 | 373 | ||
@@ -409,7 +422,7 @@ void __init set_highmem_pages_init(int bad_ppro) | |||
409 | zone_end_pfn = zone_start_pfn + zone->spanned_pages; | 422 | zone_end_pfn = zone_start_pfn + zone->spanned_pages; |
410 | 423 | ||
411 | printk("Initializing %s for node %d (%08lx:%08lx)\n", | 424 | printk("Initializing %s for node %d (%08lx:%08lx)\n", |
412 | zone->name, zone->zone_pgdat->node_id, | 425 | zone->name, zone_to_nid(zone), |
413 | zone_start_pfn, zone_end_pfn); | 426 | zone_start_pfn, zone_end_pfn); |
414 | 427 | ||
415 | for (node_pfn = zone_start_pfn; node_pfn < zone_end_pfn; node_pfn++) { | 428 | for (node_pfn = zone_start_pfn; node_pfn < zone_end_pfn; node_pfn++) { |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 89e8486aac34..efd0bcdac65d 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -629,6 +629,48 @@ void __init mem_init(void) | |||
629 | (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)) | 629 | (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)) |
630 | ); | 630 | ); |
631 | 631 | ||
632 | #if 1 /* double-sanity-check paranoia */ | ||
633 | printk("virtual kernel memory layout:\n" | ||
634 | " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" | ||
635 | #ifdef CONFIG_HIGHMEM | ||
636 | " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n" | ||
637 | #endif | ||
638 | " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n" | ||
639 | " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n" | ||
640 | " .init : 0x%08lx - 0x%08lx (%4ld kB)\n" | ||
641 | " .data : 0x%08lx - 0x%08lx (%4ld kB)\n" | ||
642 | " .text : 0x%08lx - 0x%08lx (%4ld kB)\n", | ||
643 | FIXADDR_START, FIXADDR_TOP, | ||
644 | (FIXADDR_TOP - FIXADDR_START) >> 10, | ||
645 | |||
646 | #ifdef CONFIG_HIGHMEM | ||
647 | PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, | ||
648 | (LAST_PKMAP*PAGE_SIZE) >> 10, | ||
649 | #endif | ||
650 | |||
651 | VMALLOC_START, VMALLOC_END, | ||
652 | (VMALLOC_END - VMALLOC_START) >> 20, | ||
653 | |||
654 | (unsigned long)__va(0), (unsigned long)high_memory, | ||
655 | ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20, | ||
656 | |||
657 | (unsigned long)&__init_begin, (unsigned long)&__init_end, | ||
658 | ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10, | ||
659 | |||
660 | (unsigned long)&_etext, (unsigned long)&_edata, | ||
661 | ((unsigned long)&_edata - (unsigned long)&_etext) >> 10, | ||
662 | |||
663 | (unsigned long)&_text, (unsigned long)&_etext, | ||
664 | ((unsigned long)&_etext - (unsigned long)&_text) >> 10); | ||
665 | |||
666 | #ifdef CONFIG_HIGHMEM | ||
667 | BUG_ON(PKMAP_BASE+LAST_PKMAP*PAGE_SIZE > FIXADDR_START); | ||
668 | BUG_ON(VMALLOC_END > PKMAP_BASE); | ||
669 | #endif | ||
670 | BUG_ON(VMALLOC_START > VMALLOC_END); | ||
671 | BUG_ON((unsigned long)high_memory > VMALLOC_START); | ||
672 | #endif /* double-sanity-check paranoia */ | ||
673 | |||
632 | #ifdef CONFIG_X86_PAE | 674 | #ifdef CONFIG_X86_PAE |
633 | if (!cpu_has_pae) | 675 | if (!cpu_has_pae) |
634 | panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!"); | 676 | panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!"); |
@@ -657,7 +699,7 @@ void __init mem_init(void) | |||
657 | int arch_add_memory(int nid, u64 start, u64 size) | 699 | int arch_add_memory(int nid, u64 start, u64 size) |
658 | { | 700 | { |
659 | struct pglist_data *pgdata = &contig_page_data; | 701 | struct pglist_data *pgdata = &contig_page_data; |
660 | struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1; | 702 | struct zone *zone = pgdata->node_zones + ZONE_HIGHMEM; |
661 | unsigned long start_pfn = start >> PAGE_SHIFT; | 703 | unsigned long start_pfn = start >> PAGE_SHIFT; |
662 | unsigned long nr_pages = size >> PAGE_SHIFT; | 704 | unsigned long nr_pages = size >> PAGE_SHIFT; |
663 | 705 | ||
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index bd98768d8764..10126e3f8174 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/pagemap.h> | 13 | #include <linux/pagemap.h> |
14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
15 | #include <linux/module.h> | ||
15 | 16 | ||
16 | #include <asm/system.h> | 17 | #include <asm/system.h> |
17 | #include <asm/pgtable.h> | 18 | #include <asm/pgtable.h> |
@@ -60,7 +61,9 @@ void show_mem(void) | |||
60 | printk(KERN_INFO "%lu pages writeback\n", | 61 | printk(KERN_INFO "%lu pages writeback\n", |
61 | global_page_state(NR_WRITEBACK)); | 62 | global_page_state(NR_WRITEBACK)); |
62 | printk(KERN_INFO "%lu pages mapped\n", global_page_state(NR_FILE_MAPPED)); | 63 | printk(KERN_INFO "%lu pages mapped\n", global_page_state(NR_FILE_MAPPED)); |
63 | printk(KERN_INFO "%lu pages slab\n", global_page_state(NR_SLAB)); | 64 | printk(KERN_INFO "%lu pages slab\n", |
65 | global_page_state(NR_SLAB_RECLAIMABLE) + | ||
66 | global_page_state(NR_SLAB_UNRECLAIMABLE)); | ||
64 | printk(KERN_INFO "%lu pages pagetables\n", | 67 | printk(KERN_INFO "%lu pages pagetables\n", |
65 | global_page_state(NR_PAGETABLE)); | 68 | global_page_state(NR_PAGETABLE)); |
66 | } | 69 | } |
@@ -137,6 +140,12 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) | |||
137 | __flush_tlb_one(vaddr); | 140 | __flush_tlb_one(vaddr); |
138 | } | 141 | } |
139 | 142 | ||
143 | static int fixmaps; | ||
144 | #ifndef CONFIG_COMPAT_VDSO | ||
145 | unsigned long __FIXADDR_TOP = 0xfffff000; | ||
146 | EXPORT_SYMBOL(__FIXADDR_TOP); | ||
147 | #endif | ||
148 | |||
140 | void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) | 149 | void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) |
141 | { | 150 | { |
142 | unsigned long address = __fix_to_virt(idx); | 151 | unsigned long address = __fix_to_virt(idx); |
@@ -146,6 +155,25 @@ void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) | |||
146 | return; | 155 | return; |
147 | } | 156 | } |
148 | set_pte_pfn(address, phys >> PAGE_SHIFT, flags); | 157 | set_pte_pfn(address, phys >> PAGE_SHIFT, flags); |
158 | fixmaps++; | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * reserve_top_address - reserves a hole in the top of kernel address space | ||
163 | * @reserve - size of hole to reserve | ||
164 | * | ||
165 | * Can be used to relocate the fixmap area and poke a hole in the top | ||
166 | * of kernel address space to make room for a hypervisor. | ||
167 | */ | ||
168 | void reserve_top_address(unsigned long reserve) | ||
169 | { | ||
170 | BUG_ON(fixmaps > 0); | ||
171 | #ifdef CONFIG_COMPAT_VDSO | ||
172 | BUG_ON(reserve != 0); | ||
173 | #else | ||
174 | __FIXADDR_TOP = -reserve - PAGE_SIZE; | ||
175 | __VMALLOC_RESERVE += reserve; | ||
176 | #endif | ||
149 | } | 177 | } |
150 | 178 | ||
151 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | 179 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) |