diff options
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r-- | arch/powerpc/kernel/prom.c | 27 |
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 | } |
84 | early_param("mem", early_parse_mem); | 84 | early_param("mem", early_parse_mem); |
85 | 85 | ||
86 | /* | ||
87 | * overlaps_initrd - check for overlap with page aligned extension of | ||
88 | * initrd. | ||
89 | */ | ||
90 | static 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 | */ |
92 | static void __init move_device_tree(void) | 110 | static 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 |