#include <linux/initrd.h>
#include <linux/swap.h>
#include <linux/unistd.h>
+#include <linux/nodemask.h> /* for node_online_map */
+#include <linux/pagemap.h> /* for release_pages and page_cache_release */
#include <asm/pgalloc.h>
#include <asm/tlb.h>
extern char __init_begin, __init_end;
#ifdef CONFIG_DISCONTIGMEM
-struct node_map_data node_data[MAX_NUMNODES];
-bootmem_data_t bmem_data[MAX_NUMNODES];
-unsigned char pfnnid_map[PFNNID_MAP_MAX];
+struct node_map_data node_data[MAX_NUMNODES] __read_mostly;
+bootmem_data_t bmem_data[MAX_NUMNODES] __read_mostly;
+unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly;
#endif
static struct resource data_resource = {
.flags = IORESOURCE_BUSY | IORESOURCE_MEM,
};
-static struct resource sysram_resources[MAX_PHYSMEM_RANGES];
-
-static unsigned long max_pfn;
+static struct resource sysram_resources[MAX_PHYSMEM_RANGES] __read_mostly;
/* The following array is initialized from the firmware specific
* information retrieved in kernel/inventory.c.
*/
-physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES];
-int npmem_ranges;
+physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly;
+int npmem_ranges __read_mostly;
#ifdef __LP64__
#define MAX_MEM (~0UL)
#define MAX_MEM (3584U*1024U*1024U)
#endif /* !__LP64__ */
-static unsigned long mem_limit = MAX_MEM;
+static unsigned long mem_limit __read_mostly = MAX_MEM;
static void __init mem_limit_func(void)
{
size = (pmem_ranges[i].pages << PAGE_SHIFT);
start = (pmem_ranges[i].start_pfn << PAGE_SHIFT);
- printk(KERN_INFO "%2d) Start 0x%016lx End 0x%016lx Size %6ld Mb\n",
+ printk(KERN_INFO "%2d) Start 0x%016lx End 0x%016lx Size %6ld MB\n",
i,start, start + (size - 1), size >> 20);
}
}
rsize = pmem_ranges[i].pages << PAGE_SHIFT;
if ((mem_max + rsize) > mem_limit) {
- printk(KERN_WARNING "Memory truncated to %ld Mb\n", mem_limit >> 20);
+ printk(KERN_WARNING "Memory truncated to %ld MB\n", mem_limit >> 20);
if (mem_max == mem_limit)
npmem_ranges = i;
else {
mem_max += rsize;
}
- printk(KERN_INFO "Total Memory: %ld Mb\n",mem_max >> 20);
+ printk(KERN_INFO "Total Memory: %ld MB\n",mem_max >> 20);
#ifndef CONFIG_DISCONTIGMEM
/* Merge the ranges, keeping track of the holes */
}
memset(pfnnid_map, 0xff, sizeof(pfnnid_map));
- numnodes = npmem_ranges;
-
for (i = 0; i < npmem_ranges; i++)
node_set_online(i);
#endif
max_pfn = start_pfn + npages;
}
+ /* IOMMU is always used to access "high mem" on those boxes
+ * that can support enough mem that a PCI device couldn't
+ * directly DMA to any physical addresses.
+ * ISA DMA support will need to revisit this.
+ */
+ max_low_pfn = max_pfn;
+
if ((bootmap_pfn - bootmap_start_pfn) != bootmap_pages) {
printk(KERN_WARNING "WARNING! bootmap sizing is messed up!\n");
BUG();
void free_initmem(void)
{
- /* FIXME: */
-#if 0
- printk(KERN_INFO "NOT FREEING INITMEM (%dk)\n",
- (&__init_end - &__init_begin) >> 10);
- return;
-#else
unsigned long addr;
printk(KERN_INFO "Freeing unused kernel memory: ");
-#if 1
+#ifdef CONFIG_DEBUG_KERNEL
/* Attempt to catch anyone trying to execute code here
* by filling the page with BRK insns.
*
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE);
printk("%luk freed\n", (unsigned long)(&__init_end - &__init_begin) >> 10);
-#endif
}
+
+#ifdef CONFIG_DEBUG_RODATA
+void mark_rodata_ro(void)
+{
+ extern char __start_rodata, __end_rodata;
+ /* rodata memory was already mapped with KERNEL_RO access rights by
+ pagetable_init() and map_pages(). No need to do additional stuff here */
+ printk (KERN_INFO "Write protecting the kernel read-only data: %luk\n",
+ (unsigned long)(&__end_rodata - &__start_rodata) >> 10);
+}
+#endif
+
+
/*
* Just an arbitrary offset to serve as a "hole" between mapping areas
* (between top of physical memory and a potential pcxl dma mapping
#define SET_MAP_OFFSET(x) ((void *)(((unsigned long)(x) + VM_MAP_OFFSET) \
& ~(VM_MAP_OFFSET-1)))
-void *vmalloc_start;
+void *vmalloc_start __read_mostly;
EXPORT_SYMBOL(vmalloc_start);
#ifdef CONFIG_PA11
-unsigned long pcxl_dma_start;
+unsigned long pcxl_dma_start __read_mostly;
#endif
void __init mem_init(void)
#ifndef CONFIG_DISCONTIGMEM
max_mapnr = page_to_pfn(virt_to_page(high_memory - 1)) + 1;
- mem_map = zone_table[ZONE_DMA]->zone_mem_map;
totalram_pages += free_all_bootmem();
#else
{
}
-int do_check_pgt_cache(int low, int high)
-{
- return 0;
-}
-
-unsigned long *empty_zero_page;
+unsigned long *empty_zero_page __read_mostly;
void show_mem(void)
{
for (j = node_start_pfn(i); j < node_end_pfn(i); j++) {
struct page *p;
+ unsigned long flags;
- p = node_mem_map(i) + j - node_start_pfn(i);
+ pgdat_resize_lock(NODE_DATA(i), &flags);
+ p = nid_page_nr(i, j) - node_start_pfn(i);
total++;
if (PageReserved(p))
free++;
else
shared += page_count(p) - 1;
+ pgdat_resize_unlock(NODE_DATA(i), &flags);
}
}
#endif
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_end && initrd_end > mem_limit) {
- printk("initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end);
+ printk(KERN_INFO "initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end);
map_pages(initrd_start, __pa(initrd_start),
initrd_end - initrd_start, PAGE_KERNEL);
}
#if PTRS_PER_PMD == 1
pmd = (pmd_t *)__pa(pg_dir);
#else
- pmd = (pmd_t *) (PAGE_MASK & pgd_val(*pg_dir));
+ pmd = (pmd_t *) pgd_address(*pg_dir);
/*
* pmd is physical at this point
pmd = (pmd_t *) __pa(pmd);
}
- pgd_val(*pg_dir) = _PAGE_TABLE | (unsigned long) pmd;
+ __pgd_val_set(*pg_dir, PxD_FLAG_PRESENT | PxD_FLAG_VALID | (unsigned long) pmd);
#endif
/* now change pmd to kernel virtual addresses */
* pg_table is physical at this point
*/
- pg_table = (pte_t *) (PAGE_MASK & pmd_val(*pmd));
+ pg_table = (pte_t *) pmd_address(*pmd);
if (!pg_table)
pg_table = (pte_t *) __pa(get_zeroed_page(GFP_KERNEL));
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) pg_table;
+ __pmd_val_set(*pmd, PxD_FLAG_PRESENT | PxD_FLAG_VALID | (unsigned long) pg_table);
/* now change pg_table to kernel virtual addresses */
EXPORT_SYMBOL(map_hpux_gateway_page);
#endif
-extern void flush_tlb_all_local(void);
-
void __init paging_init(void)
{
int i;
pagetable_init();
gateway_init();
flush_cache_all_local(); /* start with known state */
- flush_tlb_all_local();
+ flush_tlb_all_local(NULL);
for (i = 0; i < npmem_ranges; i++) {
unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0 };
ZONE_DMA zone. */
zones_size[ZONE_DMA] = pmem_ranges[i].pages;
- free_area_init_node(i, NODE_DATA(i), zones_size,
- pmem_ranges[i].start_pfn, 0);
-
#ifdef CONFIG_DISCONTIGMEM
+ /* Need to initialize the pfnnid_map before we can initialize
+ the zone */
{
int j;
- for (j = (node_start_pfn(i) >> PFNNID_SHIFT);
- j <= (node_end_pfn(i) >> PFNNID_SHIFT);
+ for (j = (pmem_ranges[i].start_pfn >> PFNNID_SHIFT);
+ j <= ((pmem_ranges[i].start_pfn + pmem_ranges[i].pages) >> PFNNID_SHIFT);
j++) {
pfnnid_map[j] = i;
}
}
#endif
+
+ free_area_init_node(i, NODE_DATA(i), zones_size,
+ pmem_ranges[i].start_pfn, NULL);
}
}
static unsigned long free_space_ids = NR_SPACE_IDS - 1;
static unsigned long dirty_space_ids = 0;
-static spinlock_t sid_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sid_lock);
unsigned long alloc_sid(void)
{
do_recycle++;
}
spin_unlock(&sid_lock);
- on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
+ on_each_cpu(flush_tlb_all_local, NULL, 1, 1);
if (do_recycle) {
spin_lock(&sid_lock);
recycle_sids(recycle_ndirty,recycle_dirty_array);
void flush_tlb_all(void)
{
spin_lock(&sid_lock);
- flush_tlb_all_local();
+ flush_tlb_all_local(NULL);
recycle_sids();
spin_unlock(&sid_lock);
}