aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/mm')
-rw-r--r--arch/i386/mm/boot_ioremap.c7
-rw-r--r--arch/i386/mm/discontig.c33
-rw-r--r--arch/i386/mm/init.c44
-rw-r--r--arch/i386/mm/pgtable.c30
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)) 33static unsigned long boot_pte_index(unsigned long vaddr)
34{
35 return __pa(vaddr) >> PAGE_SHIFT;
36}
34 37
35static inline boot_pte_t* boot_vaddr_to_pte(void *address) 38static 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
118void *node_remap_end_vaddr[MAX_NUMNODES]; 118void *node_remap_end_vaddr[MAX_NUMNODES];
119void *node_remap_alloc_vaddr[MAX_NUMNODES]; 119void *node_remap_alloc_vaddr[MAX_NUMNODES];
120 120static unsigned long kva_start_pfn;
121static 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
359void __init numa_kva_reserve(void)
360{
361 reserve_bootmem(PFN_PHYS(kva_start_pfn),PFN_PHYS(kva_pages));
362}
363
351void __init zone_sizes_init(void) 364void __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)
657int arch_add_memory(int nid, u64 start, u64 size) 699int 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
143static int fixmaps;
144#ifndef CONFIG_COMPAT_VDSO
145unsigned long __FIXADDR_TOP = 0xfffff000;
146EXPORT_SYMBOL(__FIXADDR_TOP);
147#endif
148
140void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) 149void __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 */
168void 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
151pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) 179pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)