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