aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mm/init.c23
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)
231static void __init arm_initrd_init(void) 231static 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);