Michael, Fixed.
-Manish ---------- Initial patch for reserving memory in early boot, and freeing it later. If the previous boot had ended with a crash, the reserved memory would contain a copy of the crashed kernel data. Signed-off-by: Manish Ahuja <[EMAIL PROTECTED]> Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]> ---- arch/powerpc/kernel/prom.c | 50 ++++++++++++++++++++ arch/powerpc/kernel/rtas.c | 32 +++++++++++++ arch/powerpc/platforms/pseries/Makefile | 1 arch/powerpc/platforms/pseries/phyp_dump.c | 71 +++++++++++++++++++++++++++++ include/asm-powerpc/phyp_dump.h | 38 +++++++++++++++ include/asm-powerpc/rtas.h | 3 + 6 files changed, 195 insertions(+) Index: 2.6.24-rc5/include/asm-powerpc/phyp_dump.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.24-rc5/include/asm-powerpc/phyp_dump.h 2008-02-12 16:12:45.000000000 -0600 @@ -0,0 +1,38 @@ +/* + * Hypervisor-assisted dump + * + * Linas Vepstas, Manish Ahuja 2007 + * Copyright (c) 2007 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _PPC64_PHYP_DUMP_H +#define _PPC64_PHYP_DUMP_H + +#ifdef CONFIG_PHYP_DUMP + +/* The RMR region will be saved for later dumping + * whenever the kernel crashes. Set this to 256MB. */ +#define PHYP_DUMP_RMR_START 0x0 +#define PHYP_DUMP_RMR_END (1UL<<28) + +struct phyp_dump { + /* Memory that is reserved during very early boot. */ + unsigned long init_reserve_start; + unsigned long init_reserve_size; + /* Check status during boot if dump supported, active & present*/ + unsigned long phyp_dump_configured; + unsigned long phyp_dump_is_active; + /* store cpu & hpte size */ + unsigned long cpu_state_size; + unsigned long hpte_region_size; +}; + +extern struct phyp_dump *phyp_dump_info; + +#endif /* CONFIG_PHYP_DUMP */ +#endif /* _PPC64_PHYP_DUMP_H */ Index: 2.6.24-rc5/arch/powerpc/platforms/pseries/phyp_dump.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.24-rc5/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-12 16:12:45.000000000 -0600 @@ -0,0 +1,71 @@ +/* + * Hypervisor-assisted dump + * + * Linas Vepstas, Manish Ahuja 2007 + * Copyrhgit (c) 2007 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/pfn.h> +#include <linux/swap.h> + +#include <asm/page.h> +#include <asm/phyp_dump.h> + +/* Global, used to communicate data between early boot and late boot */ +static struct phyp_dump phyp_dump_global; +struct phyp_dump *phyp_dump_info = &phyp_dump_global; + +/** + * release_memory_range -- release memory previously lmb_reserved + * @start_pfn: starting physical frame number + * @nr_pages: number of pages to free. + * + * This routine will release memory that had been previously + * lmb_reserved in early boot. The released memory becomes + * available for genreal use. + */ +static void +release_memory_range(unsigned long start_pfn, unsigned long nr_pages) +{ + struct page *rpage; + unsigned long end_pfn; + long i; + + end_pfn = start_pfn + nr_pages; + + for (i=start_pfn; i <= end_pfn; i++) { + rpage = pfn_to_page(i); + if (PageReserved(rpage)) { + ClearPageReserved(rpage); + init_page_count(rpage); + __free_page(rpage); + totalram_pages++; + } + } +} + +static int __init phyp_dump_setup(void) +{ + unsigned long start_pfn, nr_pages; + + /* If no memory was reserved in early boot, there is nothing to do */ + if (phyp_dump_info->init_reserve_size == 0) + return 0; + + /* Release memory that was reserved in early boot */ + start_pfn = PFN_DOWN(phyp_dump_info->init_reserve_start); + nr_pages = PFN_DOWN(phyp_dump_info->init_reserve_size); + release_memory_range(start_pfn, nr_pages); + + return 0; +} + +subsys_initcall(phyp_dump_setup); Index: 2.6.24-rc5/arch/powerpc/platforms/pseries/Makefile =================================================================== --- 2.6.24-rc5.orig/arch/powerpc/platforms/pseries/Makefile 2008-02-12 16:11:44.000000000 -0600 +++ 2.6.24-rc5/arch/powerpc/platforms/pseries/Makefile 2008-02-12 16:12:45.000000000 -0600 @@ -18,3 +18,4 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_HVCS) += hvcserver.o obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o +obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o Index: 2.6.24-rc5/arch/powerpc/kernel/prom.c =================================================================== --- 2.6.24-rc5.orig/arch/powerpc/kernel/prom.c 2008-02-12 16:11:44.000000000 -0600 +++ 2.6.24-rc5/arch/powerpc/kernel/prom.c 2008-02-12 16:12:45.000000000 -0600 @@ -51,6 +51,7 @@ #include <asm/machdep.h> #include <asm/pSeries_reconfig.h> #include <asm/pci-bridge.h> +#include <asm/phyp_dump.h> #include <asm/kexec.h> #ifdef DEBUG @@ -1011,6 +1012,52 @@ static void __init early_reserve_mem(voi #endif } +#ifdef CONFIG_PHYP_DUMP +/** + * reserve_crashed_mem() - reserve all not-yet-dumped mmemory + * + * This routine may reserve memory regions in the kernel only + * if the system is supported and a dump was taken in last + * boot instance or if the hardware is supported and the + * scratch area needs to be setup. In other instances it returns + * without reserving anything. The memory in case of dump being + * active is freed when the dump is collected (by userland tools). + */ +static void __init reserve_crashed_mem(void) +{ + unsigned long base, size; + if (!phyp_dump_info->phyp_dump_configured) { + printk(KERN_ERR "Phyp-dump not supported on this hardware\n"); + return; + } + + if (phyp_dump_info->phyp_dump_is_active) { + /* Reserve *everything* above RMR.Area freed by userland tools*/ + base = PHYP_DUMP_RMR_END; + size = lmb_end_of_DRAM() - base; + + /* XXX crashed_ram_end is wrong, since it may be beyond + * the memory_limit, it will need to be adjusted. */ + lmb_reserve(base, size); + + phyp_dump_info->init_reserve_start = base; + phyp_dump_info->init_reserve_size = size; + } + else { + size = phyp_dump_info->cpu_state_size + + phyp_dump_info->hpte_region_size + + PHYP_DUMP_RMR_END; + base = lmb_end_of_DRAM() - size; + lmb_reserve(base, size); + phyp_dump_info->init_reserve_start = base; + phyp_dump_info->init_reserve_size = size; + } +} +#else +static inline void __init reserve_crashed_mem(void) {} +#endif /* CONFIG_PHYP_DUMP */ + + void __init early_init_devtree(void *params) { DBG(" -> early_init_devtree(%p)\n", params); @@ -1022,6 +1069,8 @@ void __init early_init_devtree(void *par /* Some machines might need RTAS info for debugging, grab it now. */ of_scan_flat_dt(early_init_dt_scan_rtas, NULL); #endif + /* scan tree to see if dump occured during last boot */ + of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL); /* Retrieve various informations from the /chosen node of the * device-tree, including the platform type, initrd location and @@ -1043,6 +1092,7 @@ void __init early_init_devtree(void *par reserve_kdump_trampoline(); reserve_crashkernel(); early_reserve_mem(); + reserve_crashed_mem(); lmb_enforce_memory_limit(memory_limit); lmb_analyze(); Index: 2.6.24-rc5/arch/powerpc/kernel/rtas.c =================================================================== --- 2.6.24-rc5.orig/arch/powerpc/kernel/rtas.c 2008-02-12 16:11:44.000000000 -0600 +++ 2.6.24-rc5/arch/powerpc/kernel/rtas.c 2008-02-12 16:12:45.000000000 -0600 @@ -39,6 +39,7 @@ #include <asm/syscalls.h> #include <asm/smp.h> #include <asm/atomic.h> +#include <asm/phyp_dump.h> struct rtas_t rtas = { .lock = SPIN_LOCK_UNLOCKED @@ -883,6 +884,37 @@ void __init rtas_initialize(void) #endif } +int __init early_init_dt_scan_phyp_dump(unsigned long node, + const char *uname, int depth, void *data) +{ +#ifdef CONFIG_PHYP_DUMP + const unsigned int *sizes; + + phyp_dump_info->phyp_dump_configured = 0; + phyp_dump_info->phyp_dump_is_active = 0; + + if (depth != 1 || strcmp(uname, "rtas") != 0) + return 0; + + if (of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL)) + phyp_dump_info->phyp_dump_configured++; + + if (of_get_flat_dt_prop(node, "ibm,dump-kernel", NULL)) + phyp_dump_info->phyp_dump_is_active++; + + sizes = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump-sizes", NULL); + if (!sizes) + return 0; + + if (sizes[0] == 1) + phyp_dump_info->cpu_state_size = *((unsigned long *)&sizes[1]); + + if (sizes[3] == 2) + phyp_dump_info->hpte_region_size = *((unsigned long *)&sizes[4]); +#endif + return 1; +} + int __init early_init_dt_scan_rtas(unsigned long node, const char *uname, int depth, void *data) { Index: 2.6.24-rc5/include/asm-powerpc/rtas.h =================================================================== --- 2.6.24-rc5.orig/include/asm-powerpc/rtas.h 2008-02-12 16:09:48.000000000 -0600 +++ 2.6.24-rc5/include/asm-powerpc/rtas.h 2008-02-12 16:12:45.000000000 -0600 @@ -183,6 +183,9 @@ extern unsigned int rtas_busy_delay(int extern int early_init_dt_scan_rtas(unsigned long node, const char *uname, int depth, void *data); +int early_init_dt_scan_phyp_dump(unsigned long node, + const char *uname, int depth, void *data); + extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev