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