Here is a set of ppc64 specific patches that at least allow compilation/booting with the following configurations: FLATMEM SPARSEMEN SPARSEMEM + MEMORY_HOTPLUG I'll continue to work the other configuration combinations and work on increased functionality. However, it would be great if these could be added to the patch set. Thanks, -- Signed-off-by: Mike Kravetz Signed-off-by: Dave Hansen --- memhotplug-dave/arch/ppc64/mm/init.c | 77 +++++++++++++++++++++++++++ memhotplug-dave/include/asm-ppc64/abs_addr.h | 2 memhotplug-dave/include/asm-ppc64/mmzone.h | 2 3 files changed, 80 insertions(+), 1 deletion(-) diff -puN arch/ppc64/Kconfig~G1-kravetz-ppc64-fixes arch/ppc64/Kconfig diff -puN arch/ppc64/kernel/setup.c~G1-kravetz-ppc64-fixes arch/ppc64/kernel/setup.c diff -puN arch/ppc64/mm/init.c~G1-kravetz-ppc64-fixes arch/ppc64/mm/init.c --- memhotplug/arch/ppc64/mm/init.c~G1-kravetz-ppc64-fixes 2005-03-11 10:52:34.000000000 -0800 +++ memhotplug-dave/arch/ppc64/mm/init.c 2005-03-11 10:52:34.000000000 -0800 @@ -926,3 +926,80 @@ void pgtable_cache_init(void) if (!zero_cache) panic("pgtable_cache_init(): could not create zero_cache!\n"); } + +#ifdef CONFIG_MEMORY_HOTPLUG + +void online_page(struct page *page) +{ + ClearPageReserved(page); + free_cold_page(page); + totalram_pages++; + num_physpages++; +} + +/* + * This works only for the non-NUMA case. Later, we'll need a lookup + * to convert from real physical addresses to nid, that doesn't use + * pfn_to_nid(). + */ +int __devinit add_memory(u64 start, u64 size, unsigned long attr) +{ + struct pglist_data *pgdata = NODE_DATA(0); + struct zone *zone; + unsigned long start_pfn = start >> PAGE_SHIFT; + unsigned long nr_pages = size >> PAGE_SHIFT; + + /* this should work for most non-highmem platforms */ + zone = pgdata->node_zones; + + return __add_pages(zone, start_pfn, nr_pages, attr); + + return 0; +} + +/* + * First pass at this code will check to determine if the remove + * request is within the RMO. Do not allow removal within the RMO. + */ +int __devinit remove_memory(u64 start, u64 size, unsigned long attr) +{ + struct zone *zone; + unsigned long start_pfn, end_pfn, nr_pages; + + start_pfn = start >> PAGE_SHIFT; + nr_pages = size >> PAGE_SHIFT; + end_pfn = start_pfn + nr_pages; + + printk("%s(): Attempting to remove memoy in range " + "%lx to %lx\n", __func__, start, start+size); + /* + * check for range within RMO + */ + zone = page_zone(pfn_to_page(start_pfn)); + + printk("%s(): memory will be removed from " + "the %s zone\n", __func__, zone->name); + + /* + * not handling removing memory ranges that + * overlap multiple zones yet + */ + if (end_pfn > (zone->zone_start_pfn + zone->spanned_pages)) + goto overlap; + + /* make sure it is NOT in RMO */ + if ((start < lmb.rmo_size) || ((start+size) < lmb.rmo_size)) { + printk("%s(): range to be removed must NOT be in RMO!\n", + __func__); + goto in_rmo; + } + + return __remove_pages(zone, start_pfn, nr_pages, attr); + +overlap: + printk("%s(): memory range to be removed overlaps " + "multiple zones!!!\n", __func__); +in_rmo: + return -1; +} +#endif /* CONFIG_MEMORY_HOTPLUG */ diff -puN include/asm-ppc64/abs_addr.h~G1-kravetz-ppc64-fixes include/asm-ppc64/abs_addr.h --- memhotplug/include/asm-ppc64/abs_addr.h~G1-kravetz-ppc64-fixes 2005-03-11 10:52:34.000000000 -0800 +++ memhotplug-dave/include/asm-ppc64/abs_addr.h 2005-03-11 10:52:34.000000000 -0800 @@ -104,5 +104,7 @@ physRpn_to_absRpn(unsigned long rpn) /* Convenience macros */ #define virt_to_abs(va) phys_to_abs(__pa(va)) #define abs_to_virt(aa) __va(abs_to_phys(aa)) +#define boot_virt_to_abs(va) phys_to_abs(__boot_pa(va)) +#define boot_abs_to_virt(aa) __boot_va(abs_to_phys(aa)) #endif /* _ABS_ADDR_H */ diff -puN include/asm-ppc64/mmzone.h~G1-kravetz-ppc64-fixes include/asm-ppc64/mmzone.h --- memhotplug/include/asm-ppc64/mmzone.h~G1-kravetz-ppc64-fixes 2005-03-11 10:52:34.000000000 -0800 +++ memhotplug-dave/include/asm-ppc64/mmzone.h 2005-03-11 10:52:34.000000000 -0800 @@ -48,7 +48,7 @@ extern int nr_cpus_in_node[]; #define MEMORY_INCREMENT_SHIFT 24 #define MEMORY_INCREMENT (1UL << MEMORY_INCREMENT_SHIFT) -#endif /* !CONFIG_DISCONTIGMEM || !CONFIG_SPARSEMEM */ +#endif /* CONFIG_DISCONTIGMEM || CONFIG_SPARSEMEM */ #ifdef CONFIG_DISCONTIGMEM _