diff options
| -rw-r--r-- | arch/arm/mm/init.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 15739a95552a..d1e26610977d 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
| @@ -231,6 +231,9 @@ phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align) | |||
| 231 | static void __init arm_initrd_init(void) | 231 | static void __init arm_initrd_init(void) |
| 232 | { | 232 | { |
| 233 | #ifdef CONFIG_BLK_DEV_INITRD | 233 | #ifdef CONFIG_BLK_DEV_INITRD |
| 234 | phys_addr_t start; | ||
| 235 | unsigned long size; | ||
| 236 | |||
| 234 | /* FDT scan will populate initrd_start */ | 237 | /* FDT scan will populate initrd_start */ |
| 235 | if (initrd_start && !phys_initrd_size) { | 238 | if (initrd_start && !phys_initrd_size) { |
| 236 | phys_initrd_start = __virt_to_phys(initrd_start); | 239 | phys_initrd_start = __virt_to_phys(initrd_start); |
| @@ -242,19 +245,29 @@ static void __init arm_initrd_init(void) | |||
| 242 | if (!phys_initrd_size) | 245 | if (!phys_initrd_size) |
| 243 | return; | 246 | return; |
| 244 | 247 | ||
| 245 | if (!memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) { | 248 | /* |
| 249 | * Round the memory region to page boundaries as per free_initrd_mem() | ||
| 250 | * This allows us to detect whether the pages overlapping the initrd | ||
| 251 | * are in use, but more importantly, reserves the entire set of pages | ||
| 252 | * as we don't want these pages allocated for other purposes. | ||
| 253 | */ | ||
| 254 | start = round_down(phys_initrd_start, PAGE_SIZE); | ||
| 255 | size = phys_initrd_size + (phys_initrd_start - start); | ||
| 256 | size = round_up(size, PAGE_SIZE); | ||
| 257 | |||
| 258 | if (!memblock_is_region_memory(start, size)) { | ||
| 246 | pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region - disabling initrd\n", | 259 | pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region - disabling initrd\n", |
| 247 | (u64)phys_initrd_start, phys_initrd_size); | 260 | (u64)start, size); |
| 248 | return; | 261 | return; |
| 249 | } | 262 | } |
| 250 | 263 | ||
| 251 | if (memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) { | 264 | if (memblock_is_region_reserved(start, size)) { |
| 252 | pr_err("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region - disabling initrd\n", | 265 | pr_err("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region - disabling initrd\n", |
| 253 | (u64)phys_initrd_start, phys_initrd_size); | 266 | (u64)start, size); |
| 254 | return; | 267 | return; |
| 255 | } | 268 | } |
| 256 | 269 | ||
| 257 | memblock_reserve(phys_initrd_start, phys_initrd_size); | 270 | memblock_reserve(start, size); |
| 258 | 271 | ||
| 259 | /* Now convert initrd to virtual addresses */ | 272 | /* Now convert initrd to virtual addresses */ |
| 260 | initrd_start = __phys_to_virt(phys_initrd_start); | 273 | initrd_start = __phys_to_virt(phys_initrd_start); |
