* Copyright (C) 2002,2003 Andi Kleen <ak@suse.de>
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <linux/proc_fs.h>
#include <linux/pci.h>
-#include <linux/poison.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/memory_hotplug.h>
#include <asm/proto.h>
#include <asm/smp.h>
#include <asm/sections.h>
+#include <asm/dma-mapping.h>
+#include <asm/swiotlb.h>
#ifndef Dprintk
#define Dprintk(x...)
printk(KERN_INFO "%lu pages swap cached\n",cached);
}
+/* References to section boundaries */
+
int after_bootmem;
static __init void *spp_getpage(void)
for (i = 0; i < PTRS_PER_PMD; pmd++, i++, address += PMD_SIZE) {
unsigned long entry;
- if (address >= end) {
- if (!after_bootmem)
- for (; i < PTRS_PER_PMD; i++, pmd++)
- set_pmd(pmd, __pmd(0));
+ if (address > end) {
+ for (; i < PTRS_PER_PMD; i++, pmd++)
+ set_pmd(pmd, __pmd(0));
break;
}
entry = _PAGE_NX|_PAGE_PSE|_KERNPG_TABLE|_PAGE_GLOBAL|address;
table_start >>= PAGE_SHIFT;
table_end = table_start;
+
+ early_printk("kernel direct mapping tables up to %lx @ %lx-%lx\n",
+ end, table_start << PAGE_SHIFT, table_end << PAGE_SHIFT);
}
/* Setup the direct mapping of the physical memory at PAGE_OFFSET.
pud_t *pud;
if (after_bootmem)
- pud = pud_offset(pgd, start & PGDIR_MASK);
+ pud = pud_offset_k(pgd, start & PGDIR_MASK);
else
pud = alloc_low_page(&map, &pud_phys);
/*
* Memory hotplug specific functions
*/
+#if defined(CONFIG_ACPI_HOTPLUG_MEMORY) || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)
+
void online_page(struct page *page)
{
ClearPageReserved(page);
num_physpages++;
}
-#ifdef CONFIG_MEMORY_HOTPLUG
+#ifndef CONFIG_MEMORY_HOTPLUG
/*
- * XXX: memory_add_physaddr_to_nid() is to find node id from physical address
- * via probe interface of sysfs. If acpi notifies hot-add event, then it
- * can tell node id by searching dsdt. But, probe interface doesn't have
- * node id. So, return 0 as node id at this time.
+ * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance,
+ * just online the pages.
*/
-#ifdef CONFIG_NUMA
-int memory_add_physaddr_to_nid(u64 start)
+int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages)
{
- return 0;
+ int err = -EIO;
+ unsigned long pfn;
+ unsigned long total = 0, mem = 0;
+ for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) {
+ if (pfn_valid(pfn)) {
+ online_page(pfn_to_page(pfn));
+ err = 0;
+ mem++;
+ }
+ total++;
+ }
+ if (!err) {
+ z->spanned_pages += total;
+ z->present_pages += mem;
+ z->zone_pgdat->node_spanned_pages += total;
+ z->zone_pgdat->node_present_pages += mem;
+ }
+ return err;
}
#endif
* Memory is added always to NORMAL zone. This means you will never get
* additional DMA/DMA32 memory.
*/
-int arch_add_memory(int nid, u64 start, u64 size)
+int add_memory(u64 start, u64 size)
{
- struct pglist_data *pgdat = NODE_DATA(nid);
+ struct pglist_data *pgdat = NODE_DATA(0);
struct zone *zone = pgdat->node_zones + MAX_NR_ZONES-2;
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
printk("%s: Problem encountered in __add_pages!\n", __func__);
return ret;
}
-EXPORT_SYMBOL_GPL(arch_add_memory);
+EXPORT_SYMBOL_GPL(add_memory);
int remove_memory(u64 start, u64 size)
{
}
EXPORT_SYMBOL_GPL(remove_memory);
-#else /* CONFIG_MEMORY_HOTPLUG */
-/*
- * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance,
- * just online the pages.
- */
-int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages)
-{
- int err = -EIO;
- unsigned long pfn;
- unsigned long total = 0, mem = 0;
- for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) {
- if (pfn_valid(pfn)) {
- online_page(pfn_to_page(pfn));
- err = 0;
- mem++;
- }
- total++;
- }
- if (!err) {
- z->spanned_pages += total;
- z->present_pages += mem;
- z->zone_pgdat->node_spanned_pages += total;
- z->zone_pgdat->node_present_pages += mem;
- }
- return err;
-}
-#endif /* CONFIG_MEMORY_HOTPLUG */
+#endif
/*
* devmem_is_allowed() checks to see if /dev/mem access to a certain address is
{
long codesize, reservedpages, datasize, initsize;
- pci_iommu_alloc();
+#ifdef CONFIG_SWIOTLB
+ pci_swiotlb_init();
+#endif
+ no_iommu_init();
/* How many end-of-memory variables you have, grandma! */
max_low_pfn = end_pfn;
#endif
}
-void free_init_pages(char *what, unsigned long begin, unsigned long end)
+void free_initmem(void)
{
unsigned long addr;
- if (begin >= end)
- return;
-
- printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
- for (addr = begin; addr < end; addr += PAGE_SIZE) {
+ addr = (unsigned long)(&__init_begin);
+ for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
init_page_count(virt_to_page(addr));
- memset((void *)(addr & ~(PAGE_SIZE-1)),
- POISON_FREE_INITMEM, PAGE_SIZE);
+ memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE);
free_page(addr);
totalram_pages++;
}
-}
-
-void free_initmem(void)
-{
- memset(__initdata_begin, POISON_FREE_INITDATA,
- __initdata_end - __initdata_begin);
- free_init_pages("unused kernel memory",
- (unsigned long)(&__init_begin),
- (unsigned long)(&__init_end));
+ memset(__initdata_begin, 0xba, __initdata_end - __initdata_begin);
+ printk ("Freeing unused kernel memory: %luk freed\n", (__init_end - __init_begin) >> 10);
}
#ifdef CONFIG_DEBUG_RODATA
+extern char __start_rodata, __end_rodata;
void mark_rodata_ro(void)
{
- unsigned long addr = (unsigned long)__start_rodata;
+ unsigned long addr = (unsigned long)&__start_rodata;
- for (; addr < (unsigned long)__end_rodata; addr += PAGE_SIZE)
+ for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
change_page_attr_addr(addr, 1, PAGE_KERNEL_RO);
printk ("Write protecting the kernel read-only data: %luk\n",
- (__end_rodata - __start_rodata) >> 10);
+ (&__end_rodata - &__start_rodata) >> 10);
/*
* change_page_attr_addr() requires a global_flush_tlb() call after it.
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
- free_init_pages("initrd memory", start, end);
+ if (start >= end)
+ return;
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(start));
+ init_page_count(virt_to_page(start));
+ free_page(start);
+ totalram_pages++;
+ }
}
#endif