aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManish Ahuja <ahuja@austin.ibm.com>2008-03-21 19:37:08 -0400
committerPaul Mackerras <paulus@samba.org>2008-03-25 17:44:06 -0400
commit6ac26c8a7eb149dbd669cc6cd9b77ffc9cd0d2fb (patch)
tree4eb613ed5f8eb7accb042e30c89d9d25097d557f
parentd28a79326a4028dbb1755b8efe6daa915d8bfeea (diff)
[POWERPC] pseries: phyp dump: Reserve and release memory
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 <mahuja@us.ibm.com> Signed-off-by: Linas Vepstas <linasvepstas@gmail.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/prom.c52
-rw-r--r--arch/powerpc/platforms/pseries/Makefile1
-rw-r--r--arch/powerpc/platforms/pseries/phyp_dump.c103
-rw-r--r--include/asm-powerpc/phyp_dump.h41
4 files changed, 197 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index ff600ef0b4d6..e6c022ef12ee 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -51,6 +51,7 @@
51#include <asm/machdep.h> 51#include <asm/machdep.h>
52#include <asm/pSeries_reconfig.h> 52#include <asm/pSeries_reconfig.h>
53#include <asm/pci-bridge.h> 53#include <asm/pci-bridge.h>
54#include <asm/phyp_dump.h>
54#include <asm/kexec.h> 55#include <asm/kexec.h>
55 56
56#ifdef DEBUG 57#ifdef DEBUG
@@ -1040,6 +1041,51 @@ static void __init early_reserve_mem(void)
1040#endif 1041#endif
1041} 1042}
1042 1043
1044#ifdef CONFIG_PHYP_DUMP
1045/**
1046 * phyp_dump_reserve_mem() - reserve all not-yet-dumped mmemory
1047 *
1048 * This routine may reserve memory regions in the kernel only
1049 * if the system is supported and a dump was taken in last
1050 * boot instance or if the hardware is supported and the
1051 * scratch area needs to be setup. In other instances it returns
1052 * without reserving anything. The memory in case of dump being
1053 * active is freed when the dump is collected (by userland tools).
1054 */
1055static void __init phyp_dump_reserve_mem(void)
1056{
1057 unsigned long base, size;
1058 if (!phyp_dump_info->phyp_dump_configured) {
1059 printk(KERN_ERR "Phyp-dump not supported on this hardware\n");
1060 return;
1061 }
1062
1063 if (phyp_dump_info->phyp_dump_is_active) {
1064 /* Reserve *everything* above RMR.Area freed by userland tools*/
1065 base = PHYP_DUMP_RMR_END;
1066 size = lmb_end_of_DRAM() - base;
1067
1068 /* XXX crashed_ram_end is wrong, since it may be beyond
1069 * the memory_limit, it will need to be adjusted. */
1070 lmb_reserve(base, size);
1071
1072 phyp_dump_info->init_reserve_start = base;
1073 phyp_dump_info->init_reserve_size = size;
1074 } else {
1075 size = phyp_dump_info->cpu_state_size +
1076 phyp_dump_info->hpte_region_size +
1077 PHYP_DUMP_RMR_END;
1078 base = lmb_end_of_DRAM() - size;
1079 lmb_reserve(base, size);
1080 phyp_dump_info->init_reserve_start = base;
1081 phyp_dump_info->init_reserve_size = size;
1082 }
1083}
1084#else
1085static inline void __init phyp_dump_reserve_mem(void) {}
1086#endif /* CONFIG_PHYP_DUMP && CONFIG_PPC_RTAS */
1087
1088
1043void __init early_init_devtree(void *params) 1089void __init early_init_devtree(void *params)
1044{ 1090{
1045 DBG(" -> early_init_devtree(%p)\n", params); 1091 DBG(" -> early_init_devtree(%p)\n", params);
@@ -1052,6 +1098,11 @@ void __init early_init_devtree(void *params)
1052 of_scan_flat_dt(early_init_dt_scan_rtas, NULL); 1098 of_scan_flat_dt(early_init_dt_scan_rtas, NULL);
1053#endif 1099#endif
1054 1100
1101#ifdef CONFIG_PHYP_DUMP
1102 /* scan tree to see if dump occured during last boot */
1103 of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL);
1104#endif
1105
1055 /* Retrieve various informations from the /chosen node of the 1106 /* Retrieve various informations from the /chosen node of the
1056 * device-tree, including the platform type, initrd location and 1107 * device-tree, including the platform type, initrd location and
1057 * size, TCE reserve, and more ... 1108 * size, TCE reserve, and more ...
@@ -1072,6 +1123,7 @@ void __init early_init_devtree(void *params)
1072 reserve_kdump_trampoline(); 1123 reserve_kdump_trampoline();
1073 reserve_crashkernel(); 1124 reserve_crashkernel();
1074 early_reserve_mem(); 1125 early_reserve_mem();
1126 phyp_dump_reserve_mem();
1075 1127
1076 lmb_enforce_memory_limit(memory_limit); 1128 lmb_enforce_memory_limit(memory_limit);
1077 lmb_analyze(); 1129 lmb_analyze();
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 992ba6753cf2..bdae04bb7a01 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o
18obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o 18obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
19obj-$(CONFIG_HVCS) += hvcserver.o 19obj-$(CONFIG_HVCS) += hvcserver.o
20obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o 20obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o
21obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o
diff --git a/arch/powerpc/platforms/pseries/phyp_dump.c b/arch/powerpc/platforms/pseries/phyp_dump.c
new file mode 100644
index 000000000000..230286cafffe
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/phyp_dump.c
@@ -0,0 +1,103 @@
1/*
2 * Hypervisor-assisted dump
3 *
4 * Linas Vepstas, Manish Ahuja 2008
5 * Copyright 2008 IBM Corp.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 */
13
14#include <linux/init.h>
15#include <linux/mm.h>
16#include <linux/pfn.h>
17#include <linux/swap.h>
18
19#include <asm/page.h>
20#include <asm/phyp_dump.h>
21#include <asm/machdep.h>
22#include <asm/prom.h>
23
24/* Variables, used to communicate data between early boot and late boot */
25static struct phyp_dump phyp_dump_vars;
26struct phyp_dump *phyp_dump_info = &phyp_dump_vars;
27
28/**
29 * release_memory_range -- release memory previously lmb_reserved
30 * @start_pfn: starting physical frame number
31 * @nr_pages: number of pages to free.
32 *
33 * This routine will release memory that had been previously
34 * lmb_reserved in early boot. The released memory becomes
35 * available for genreal use.
36 */
37static void
38release_memory_range(unsigned long start_pfn, unsigned long nr_pages)
39{
40 struct page *rpage;
41 unsigned long end_pfn;
42 long i;
43
44 end_pfn = start_pfn + nr_pages;
45
46 for (i = start_pfn; i <= end_pfn; i++) {
47 rpage = pfn_to_page(i);
48 if (PageReserved(rpage)) {
49 ClearPageReserved(rpage);
50 init_page_count(rpage);
51 __free_page(rpage);
52 totalram_pages++;
53 }
54 }
55}
56
57static int __init phyp_dump_setup(void)
58{
59 unsigned long start_pfn, nr_pages;
60
61 /* If no memory was reserved in early boot, there is nothing to do */
62 if (phyp_dump_info->init_reserve_size == 0)
63 return 0;
64
65 /* Release memory that was reserved in early boot */
66 start_pfn = PFN_DOWN(phyp_dump_info->init_reserve_start);
67 nr_pages = PFN_DOWN(phyp_dump_info->init_reserve_size);
68 release_memory_range(start_pfn, nr_pages);
69
70 return 0;
71}
72machine_subsys_initcall(pseries, phyp_dump_setup);
73
74int __init early_init_dt_scan_phyp_dump(unsigned long node,
75 const char *uname, int depth, void *data)
76{
77 const unsigned int *sizes;
78
79 phyp_dump_info->phyp_dump_configured = 0;
80 phyp_dump_info->phyp_dump_is_active = 0;
81
82 if (depth != 1 || strcmp(uname, "rtas") != 0)
83 return 0;
84
85 if (of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL))
86 phyp_dump_info->phyp_dump_configured++;
87
88 if (of_get_flat_dt_prop(node, "ibm,dump-kernel", NULL))
89 phyp_dump_info->phyp_dump_is_active++;
90
91 sizes = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump-sizes",
92 NULL);
93 if (!sizes)
94 return 0;
95
96 if (sizes[0] == 1)
97 phyp_dump_info->cpu_state_size = *((unsigned long *)&sizes[1]);
98
99 if (sizes[3] == 2)
100 phyp_dump_info->hpte_region_size =
101 *((unsigned long *)&sizes[4]);
102 return 1;
103}
diff --git a/include/asm-powerpc/phyp_dump.h b/include/asm-powerpc/phyp_dump.h
new file mode 100644
index 000000000000..e2d988dcdc99
--- /dev/null
+++ b/include/asm-powerpc/phyp_dump.h
@@ -0,0 +1,41 @@
1/*
2 * Hypervisor-assisted dump
3 *
4 * Linas Vepstas, Manish Ahuja 2008
5 * Copyright 2008 IBM Corp.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13#ifndef _PPC64_PHYP_DUMP_H
14#define _PPC64_PHYP_DUMP_H
15
16#ifdef CONFIG_PHYP_DUMP
17
18/* The RMR region will be saved for later dumping
19 * whenever the kernel crashes. Set this to 256MB. */
20#define PHYP_DUMP_RMR_START 0x0
21#define PHYP_DUMP_RMR_END (1UL<<28)
22
23struct phyp_dump {
24 /* Memory that is reserved during very early boot. */
25 unsigned long init_reserve_start;
26 unsigned long init_reserve_size;
27 /* Check status during boot if dump supported, active & present*/
28 unsigned long phyp_dump_configured;
29 unsigned long phyp_dump_is_active;
30 /* store cpu & hpte size */
31 unsigned long cpu_state_size;
32 unsigned long hpte_region_size;
33};
34
35extern struct phyp_dump *phyp_dump_info;
36
37int early_init_dt_scan_phyp_dump(unsigned long node,
38 const char *uname, int depth, void *data);
39
40#endif /* CONFIG_PHYP_DUMP */
41#endif /* _PPC64_PHYP_DUMP_H */