aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2006-02-03 03:05:47 -0500
committerPaul Mackerras <paulus@samba.org>2006-02-07 05:32:44 -0500
commitb68239ee746760bd99a68692f4c97a28f08a5d01 (patch)
tree716746e0faca1db7691f53c8d85ae72bddc5d001
parentb4fd884a037c791a39f2f03da719e251af176a97 (diff)
[PATCH] powerpc: Don't overwrite flat device tree with kdump kernel
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@ellerman.id.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/prom.c27
-rw-r--r--arch/powerpc/kernel/setup_64.c3
-rw-r--r--include/asm-powerpc/prom.h2
3 files changed, 32 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 535a33e4aa37..2b062853bcc7 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1922,3 +1922,30 @@ int prom_update_property(struct device_node *np,
1922 1922
1923 return 0; 1923 return 0;
1924} 1924}
1925
1926#ifdef CONFIG_KEXEC
1927/* We may have allocated the flat device tree inside the crash kernel region
1928 * in prom_init. If so we need to move it out into regular memory. */
1929void kdump_move_device_tree(void)
1930{
1931 unsigned long start, end;
1932 struct boot_param_header *new;
1933
1934 start = __pa((unsigned long)initial_boot_params);
1935 end = start + initial_boot_params->totalsize;
1936
1937 if (end < crashk_res.start || start > crashk_res.end)
1938 return;
1939
1940 new = (struct boot_param_header*)
1941 __va(lmb_alloc(initial_boot_params->totalsize, PAGE_SIZE));
1942
1943 memcpy(new, initial_boot_params, initial_boot_params->totalsize);
1944
1945 initial_boot_params = new;
1946
1947 DBG("Flat device tree blob moved to %p\n", initial_boot_params);
1948
1949 /* XXX should we unreserve the old DT? */
1950}
1951#endif /* CONFIG_KEXEC */
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index e29b275e09e0..a717dff695ef 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -398,6 +398,9 @@ void __init setup_system(void)
398{ 398{
399 DBG(" -> setup_system()\n"); 399 DBG(" -> setup_system()\n");
400 400
401#ifdef CONFIG_KEXEC
402 kdump_move_device_tree();
403#endif
401 /* 404 /*
402 * Unflatten the device-tree passed by prom_init or kexec 405 * Unflatten the device-tree passed by prom_init or kexec
403 */ 406 */
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index 5b2bd4eefb01..cbd297f44cce 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -222,5 +222,7 @@ extern int of_address_to_resource(struct device_node *dev, int index,
222extern int of_pci_address_to_resource(struct device_node *dev, int bar, 222extern int of_pci_address_to_resource(struct device_node *dev, int bar,
223 struct resource *r); 223 struct resource *r);
224 224
225extern void kdump_move_device_tree(void);
226
225#endif /* __KERNEL__ */ 227#endif /* __KERNEL__ */
226#endif /* _POWERPC_PROM_H */ 228#endif /* _POWERPC_PROM_H */