summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-06-14 15:51:10 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-14 15:51:23 +0200
commitdcc854579059ff9633db4dc41c681371d22f794e (patch)
tree985489cf3efcb1fcaa193237fb8674d530c188dd /arch/powerpc/kernel/prom.c
parentusb: renesas_usbhs: add DMAEngine support (diff)
parentLinux 3.0-rc3 (diff)
downloadlinux-dcc854579059ff9633db4dc41c681371d22f794e.tar.xz
linux-dcc854579059ff9633db4dc41c681371d22f794e.zip
Merge 3.0-rc2 into usb-linus as it's needed by some USB patches
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r--arch/powerpc/kernel/prom.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index f2c906b1d8d3..8c3112a57cf2 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -82,11 +82,29 @@ static int __init early_parse_mem(char *p)
}
early_param("mem", early_parse_mem);
+/*
+ * overlaps_initrd - check for overlap with page aligned extension of
+ * initrd.
+ */
+static inline int overlaps_initrd(unsigned long start, unsigned long size)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (!initrd_start)
+ return 0;
+
+ return (start + size) > _ALIGN_DOWN(initrd_start, PAGE_SIZE) &&
+ start <= _ALIGN_UP(initrd_end, PAGE_SIZE);
+#else
+ return 0;
+#endif
+}
+
/**
* move_device_tree - move tree to an unused area, if needed.
*
* The device tree may be allocated beyond our memory limit, or inside the
- * crash kernel region for kdump. If so, move it out of the way.
+ * crash kernel region for kdump, or within the page aligned range of initrd.
+ * If so, move it out of the way.
*/
static void __init move_device_tree(void)
{
@@ -99,7 +117,8 @@ static void __init move_device_tree(void)
size = be32_to_cpu(initial_boot_params->totalsize);
if ((memory_limit && (start + size) > PHYSICAL_START + memory_limit) ||
- overlaps_crashkernel(start, size)) {
+ overlaps_crashkernel(start, size) ||
+ overlaps_initrd(start, size)) {
p = __va(memblock_alloc(size, PAGE_SIZE));
memcpy(p, initial_boot_params, size);
initial_boot_params = (struct boot_param_header *)p;
@@ -555,7 +574,9 @@ static void __init early_reserve_mem(void)
#ifdef CONFIG_BLK_DEV_INITRD
/* then reserve the initrd, if any */
if (initrd_start && (initrd_end > initrd_start))
- memblock_reserve(__pa(initrd_start), initrd_end - initrd_start);
+ memblock_reserve(_ALIGN_DOWN(__pa(initrd_start), PAGE_SIZE),
+ _ALIGN_UP(initrd_end, PAGE_SIZE) -
+ _ALIGN_DOWN(initrd_start, PAGE_SIZE));
#endif /* CONFIG_BLK_DEV_INITRD */
#ifdef CONFIG_PPC32