@@ -345,6 +345,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
345
345
{
346
346
const unsigned long kernel_total_size = VO__end - VO__text ;
347
347
unsigned long virt_addr = LOAD_PHYSICAL_ADDR ;
348
+ unsigned long needed_size ;
348
349
349
350
/* Retain x86 boot parameters pointer passed from startup_32/64. */
350
351
boot_params = rmode ;
@@ -379,26 +380,38 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
379
380
free_mem_ptr = heap ; /* Heap */
380
381
free_mem_end_ptr = heap + BOOT_HEAP_SIZE ;
381
382
383
+ /*
384
+ * The memory hole needed for the kernel is the larger of either
385
+ * the entire decompressed kernel plus relocation table, or the
386
+ * entire decompressed kernel plus .bss and .brk sections.
387
+ *
388
+ * On X86_64, the memory is mapped with PMD pages. Round the
389
+ * size up so that the full extent of PMD pages mapped is
390
+ * included in the check against the valid memory table
391
+ * entries. This ensures the full mapped area is usable RAM
392
+ * and doesn't include any reserved areas.
393
+ */
394
+ needed_size = max (output_len , kernel_total_size );
395
+ #ifdef CONFIG_X86_64
396
+ needed_size = ALIGN (needed_size , MIN_KERNEL_ALIGN );
397
+ #endif
398
+
382
399
/* Report initial kernel position details. */
383
400
debug_putaddr (input_data );
384
401
debug_putaddr (input_len );
385
402
debug_putaddr (output );
386
403
debug_putaddr (output_len );
387
404
debug_putaddr (kernel_total_size );
405
+ debug_putaddr (needed_size );
388
406
389
407
#ifdef CONFIG_X86_64
390
408
/* Report address of 32-bit trampoline */
391
409
debug_putaddr (trampoline_32bit );
392
410
#endif
393
411
394
- /*
395
- * The memory hole needed for the kernel is the larger of either
396
- * the entire decompressed kernel plus relocation table, or the
397
- * entire decompressed kernel plus .bss and .brk sections.
398
- */
399
412
choose_random_location ((unsigned long )input_data , input_len ,
400
413
(unsigned long * )& output ,
401
- max ( output_len , kernel_total_size ) ,
414
+ needed_size ,
402
415
& virt_addr );
403
416
404
417
/* Validate memory location choices. */
0 commit comments