@@ -94,19 +94,40 @@ void __init mem_init(void)
9494#ifdef CONFIG_BLK_DEV_INITRD
9595static void __init setup_initrd (void )
9696{
97+ phys_addr_t start ;
9798 unsigned long size ;
9899
99- if (initrd_start >= initrd_end ) {
100- pr_info ("initrd not found or empty" );
100+ /* Ignore the virtul address computed during device tree parsing */
101+ initrd_start = initrd_end = 0 ;
102+
103+ if (!phys_initrd_size )
104+ return ;
105+ /*
106+ * Round the memory region to page boundaries as per free_initrd_mem()
107+ * This allows us to detect whether the pages overlapping the initrd
108+ * are in use, but more importantly, reserves the entire set of pages
109+ * as we don't want these pages allocated for other purposes.
110+ */
111+ start = round_down (phys_initrd_start , PAGE_SIZE );
112+ size = phys_initrd_size + (phys_initrd_start - start );
113+ size = round_up (size , PAGE_SIZE );
114+
115+ if (!memblock_is_region_memory (start , size )) {
116+ pr_err ("INITRD: 0x%08llx+0x%08lx is not a memory region" ,
117+ (u64 )start , size );
101118 goto disable ;
102119 }
103- if (__pa_symbol (initrd_end ) > PFN_PHYS (max_low_pfn )) {
104- pr_err ("initrd extends beyond end of memory" );
120+
121+ if (memblock_is_region_reserved (start , size )) {
122+ pr_err ("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region\n" ,
123+ (u64 )start , size );
105124 goto disable ;
106125 }
107126
108- size = initrd_end - initrd_start ;
109- memblock_reserve (__pa_symbol (initrd_start ), size );
127+ memblock_reserve (start , size );
128+ /* Now convert initrd to virtual addresses */
129+ initrd_start = (unsigned long )__va (phys_initrd_start );
130+ initrd_end = initrd_start + phys_initrd_size ;
110131 initrd_below_start_ok = 1 ;
111132
112133 pr_info ("Initial ramdisk at: 0x%p (%lu bytes)\n" ,
0 commit comments