[PATCH] powerpc: Don't overwrite flat device tree with kdump kernel

Michael Ellerman michael at ellerman.id.au
Fri Feb 3 19:05:47 EST 2006


It's possible for prom_init to allocate the flat device tree inside the
kdump crash kernel region. If this happens, when we load the kdump kernel we
overwrite the flattened device tree, which is bad.

We could make prom_init try and avoid allocating inside the crash kernel
region, but then we run into issues if the crash kernel region uses all the
space inside the RMO. The easiest solution is to move the flat device tree
once we're running in the kernel.

Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
---

 arch/powerpc/kernel/prom.c     |   27 +++++++++++++++++++++++++++
 arch/powerpc/kernel/setup_64.c |    3 +++
 include/asm-powerpc/prom.h     |    2 ++
 3 files changed, 32 insertions(+)

Index: kdump/arch/powerpc/kernel/prom.c
===================================================================
--- kdump.orig/arch/powerpc/kernel/prom.c
+++ kdump/arch/powerpc/kernel/prom.c
@@ -1913,3 +1913,30 @@ int prom_update_property(struct device_n
 
 	return 0;
 }
+
+#ifdef CONFIG_KEXEC
+/* We may have allocated the flat device tree inside the crash kernel region
+ * in prom_init. If so we need to move it out into regular memory. */
+void kdump_move_device_tree(void)
+{
+	unsigned long start, end;
+	struct boot_param_header *new;
+
+	start = __pa((unsigned long)initial_boot_params);
+	end = start + initial_boot_params->totalsize;
+
+	if (end < crashk_res.start || start > crashk_res.end)
+		return;
+
+	new = (struct boot_param_header*)
+		__va(lmb_alloc(initial_boot_params->totalsize, PAGE_SIZE));
+
+	memcpy(new, initial_boot_params, initial_boot_params->totalsize);
+
+	initial_boot_params = new;
+
+	DBG("Flat device tree blob moved to %p\n", initial_boot_params);
+
+	/* XXX should we unreserve the old DT? */
+}
+#endif /* CONFIG_KEXEC */
Index: kdump/arch/powerpc/kernel/setup_64.c
===================================================================
--- kdump.orig/arch/powerpc/kernel/setup_64.c
+++ kdump/arch/powerpc/kernel/setup_64.c
@@ -398,6 +398,9 @@ void __init setup_system(void)
 {
 	DBG(" -> setup_system()\n");
 
+#ifdef CONFIG_KEXEC
+	kdump_move_device_tree();
+#endif
 	/*
 	 * Unflatten the device-tree passed by prom_init or kexec
 	 */
Index: kdump/include/asm-powerpc/prom.h
===================================================================
--- kdump.orig/include/asm-powerpc/prom.h
+++ kdump/include/asm-powerpc/prom.h
@@ -222,5 +222,7 @@ extern int of_address_to_resource(struct
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
 
+extern void kdump_move_device_tree(void);
+
 #endif /* __KERNEL__ */
 #endif /* _POWERPC_PROM_H */



More information about the Linuxppc64-dev mailing list