@@ -97,6 +97,8 @@ static bool memmap_too_large;
97
97
/* Store memory limit specified by "mem=nn[KMG]" or "memmap=nn[KMG]" */
98
98
static unsigned long long mem_limit = ULLONG_MAX ;
99
99
100
+ /* Number of immovable memory regions */
101
+ static int num_immovable_mem ;
100
102
101
103
enum mem_avoid_index {
102
104
MEM_AVOID_ZO_RANGE = 0 ,
@@ -413,6 +415,9 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size,
413
415
/* Mark the memmap regions we need to avoid */
414
416
handle_mem_options ();
415
417
418
+ /* Enumerate the immovable memory regions */
419
+ num_immovable_mem = count_immovable_mem_regions ();
420
+
416
421
#ifdef CONFIG_X86_VERBOSE_BOOTUP
417
422
/* Make sure video RAM can be used. */
418
423
add_identity_map (0 , PMD_SIZE );
@@ -568,9 +573,9 @@ static unsigned long slots_fetch_random(void)
568
573
return 0 ;
569
574
}
570
575
571
- static void process_mem_region (struct mem_vector * entry ,
572
- unsigned long minimum ,
573
- unsigned long image_size )
576
+ static void __process_mem_region (struct mem_vector * entry ,
577
+ unsigned long minimum ,
578
+ unsigned long image_size )
574
579
{
575
580
struct mem_vector region , overlap ;
576
581
unsigned long start_orig , end ;
@@ -646,6 +651,56 @@ static void process_mem_region(struct mem_vector *entry,
646
651
}
647
652
}
648
653
654
+ static bool process_mem_region (struct mem_vector * region ,
655
+ unsigned long long minimum ,
656
+ unsigned long long image_size )
657
+ {
658
+ int i ;
659
+ /*
660
+ * If no immovable memory found, or MEMORY_HOTREMOVE disabled,
661
+ * use @region directly.
662
+ */
663
+ if (!num_immovable_mem ) {
664
+ __process_mem_region (region , minimum , image_size );
665
+
666
+ if (slot_area_index == MAX_SLOT_AREA ) {
667
+ debug_putstr ("Aborted e820/efi memmap scan (slot_areas full)!\n" );
668
+ return 1 ;
669
+ }
670
+ return 0 ;
671
+ }
672
+
673
+ #ifdef CONFIG_MEMORY_HOTREMOVE
674
+ /*
675
+ * If immovable memory found, filter the intersection between
676
+ * immovable memory and @region.
677
+ */
678
+ for (i = 0 ; i < num_immovable_mem ; i ++ ) {
679
+ unsigned long long start , end , entry_end , region_end ;
680
+ struct mem_vector entry ;
681
+
682
+ if (!mem_overlaps (region , & immovable_mem [i ]))
683
+ continue ;
684
+
685
+ start = immovable_mem [i ].start ;
686
+ end = start + immovable_mem [i ].size ;
687
+ region_end = region -> start + region -> size ;
688
+
689
+ entry .start = clamp (region -> start , start , end );
690
+ entry_end = clamp (region_end , start , end );
691
+ entry .size = entry_end - entry .start ;
692
+
693
+ __process_mem_region (& entry , minimum , image_size );
694
+
695
+ if (slot_area_index == MAX_SLOT_AREA ) {
696
+ debug_putstr ("Aborted e820/efi memmap scan when walking immovable regions(slot_areas full)!\n" );
697
+ return 1 ;
698
+ }
699
+ }
700
+ return 0 ;
701
+ #endif
702
+ }
703
+
649
704
#ifdef CONFIG_EFI
650
705
/*
651
706
* Returns true if mirror region found (and must have been processed
@@ -711,11 +766,8 @@ process_efi_entries(unsigned long minimum, unsigned long image_size)
711
766
712
767
region .start = md -> phys_addr ;
713
768
region .size = md -> num_pages << EFI_PAGE_SHIFT ;
714
- process_mem_region (& region , minimum , image_size );
715
- if (slot_area_index == MAX_SLOT_AREA ) {
716
- debug_putstr ("Aborted EFI scan (slot_areas full)!\n" );
769
+ if (process_mem_region (& region , minimum , image_size ))
717
770
break ;
718
- }
719
771
}
720
772
return true;
721
773
}
@@ -742,11 +794,8 @@ static void process_e820_entries(unsigned long minimum,
742
794
continue ;
743
795
region .start = entry -> addr ;
744
796
region .size = entry -> size ;
745
- process_mem_region (& region , minimum , image_size );
746
- if (slot_area_index == MAX_SLOT_AREA ) {
747
- debug_putstr ("Aborted e820 scan (slot_areas full)!\n" );
797
+ if (process_mem_region (& region , minimum , image_size ))
748
798
break ;
749
- }
750
799
}
751
800
}
752
801
0 commit comments