aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom.c
diff options
context:
space:
mode:
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 b8e6189298f4..174e1e96175e 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -83,11 +83,29 @@ static int __init early_parse_mem(char *p)
83} 83}
84early_param("mem", early_parse_mem); 84early_param("mem", early_parse_mem);
85 85
86/*
87 * overlaps_initrd - check for overlap with page aligned extension of
88 * initrd.
89 */
90static inline int overlaps_initrd(unsigned long start, unsigned long size)
91{
92#ifdef CONFIG_BLK_DEV_INITRD
93 if (!initrd_start)
94 return 0;
95
96 return (start + size) > _ALIGN_DOWN(initrd_start, PAGE_SIZE) &&
97 start <= _ALIGN_UP(initrd_end, PAGE_SIZE);
98#else
99 return 0;
100#endif
101}
102
86/** 103/**
87 * move_device_tree - move tree to an unused area, if needed. 104 * move_device_tree - move tree to an unused area, if needed.
88 * 105 *
89 * The device tree may be allocated beyond our memory limit, or inside the 106 * The device tree may be allocated beyond our memory limit, or inside the
90 * crash kernel region for kdump. If so, move it out of the way. 107 * crash kernel region for kdump, or within the page aligned range of initrd.
108 * If so, move it out of the way.
91 */ 109 */
92static void __init move_device_tree(void) 110static void __init move_device_tree(void)
93{ 111{
@@ -100,7 +118,8 @@ static void __init move_device_tree(void)
100 size = be32_to_cpu(initial_boot_params->totalsize); 118 size = be32_to_cpu(initial_boot_params->totalsize);
101 119
102 if ((memory_limit && (start + size) > PHYSICAL_START + memory_limit) || 120 if ((memory_limit && (start + size) > PHYSICAL_START + memory_limit) ||
103 overlaps_crashkernel(start, size)) { 121 overlaps_crashkernel(start, size) ||
122 overlaps_initrd(start, size)) {
104 p = __va(memblock_alloc(size, PAGE_SIZE)); 123 p = __va(memblock_alloc(size, PAGE_SIZE));
105 memcpy(p, initial_boot_params, size); 124 memcpy(p, initial_boot_params, size);
106 initial_boot_params = (struct boot_param_header *)p; 125 initial_boot_params = (struct boot_param_header *)p;
@@ -556,7 +575,9 @@ static void __init early_reserve_mem(void)
556#ifdef CONFIG_BLK_DEV_INITRD 575#ifdef CONFIG_BLK_DEV_INITRD
557 /* then reserve the initrd, if any */ 576 /* then reserve the initrd, if any */
558 if (initrd_start && (initrd_end > initrd_start)) 577 if (initrd_start && (initrd_end > initrd_start))
559 memblock_reserve(__pa(initrd_start), initrd_end - initrd_start); 578 memblock_reserve(_ALIGN_DOWN(__pa(initrd_start), PAGE_SIZE),
579 _ALIGN_UP(initrd_end, PAGE_SIZE) -
580 _ALIGN_DOWN(initrd_start, PAGE_SIZE));
560#endif /* CONFIG_BLK_DEV_INITRD */ 581#endif /* CONFIG_BLK_DEV_INITRD */
561 582
562#ifdef CONFIG_PPC32 583#ifdef CONFIG_PPC32