x86: make 'mem=' option to work for efi platform
PATCH v4 1/1 x86: make 'mem=' option to work for efi platform
Current mem boot option only can work for non efi environment. If the user specifies add_efi_memmap, it cannot work for efi environment. In the efi environment, we call e820_add_region() to add the memory map. So we can modify __e820_add_region() and the mem boot option can work for efi environment.
Note: Only E820_RAM is limited, and BOOT_SERVICES_{CODE,DATA} are always mapped(If its address >= mem_limit, the memory won't be freed in efi_free_boot_services()).
Changelogs from v3 to v4:
1. address the comment from Matt Fleming <[email protected]>:
a. only ignoring E820_RAM entries that are above the mem_limit b. don't ignore E820_RAM entries which are BOOT_SERVICES_{CODE,DATA} regions
--- arch/x86/include/asm/e820.h | 2 ++ arch/x86/kernel/e820.c | 72 +++++++++++++++++++++++++++++++++++++++------ arch/x86/platform/efi/efi.c | 15 ++++++++-- 3 files changed, 77 insertions(+), 12 deletions(-)
arch/x86/include/asm/e820.h +2 -0
@@ -84,6 +84,8 @@ extern unsigned long pci_mem_start;extern int e820_any_mapped (u64 start,u64 end,unsigned type);extern int e820_all_mapped (u64 start,u64 end,unsigned type);extern void e820_add_region (u64 start,u64 size,int type); +extern void e820_add_limit_region (u64 start,u64 size,int type); +extern void e820_adjust_region (u64 *start,u64 *size);extern void e820_print_map (char *who);extern int sanitize_e820_map (struct e820entry *biosmap,int max_nr_map,u32 *pnr_map);
arch/x86/kernel/e820.c +63 -9
128 lines not on this page · raw message
arch/x86/platform/efi/efi.c +12 -3
@@ -314,10 +314,17 @@ static void __init do_add_efi_memmap(void)int e820_type;switch (md->type) { -case EFI_LOADER_CODE : -case EFI_LOADER_DATA :case EFI_BOOT_SERVICES_CODE :case EFI_BOOT_SERVICES_DATA : +/* EFI_BOOT_SERVICES_{CODE,DATA} needs to be mapped */ +if (md->attribute &EFI_MEMORY_WB ) + e820_type =E820_RAM ; +else + e820_type =E820_RESERVED ; +e820_add_region (start, size, e820_type); +continue ; +case EFI_LOADER_CODE : +case EFI_LOADER_DATA :case EFI_CONVENTIONAL_MEMORY :if (md->attribute &EFI_MEMORY_WB ) e820_type =E820_RAM ;
@@ -342,7 +349,7 @@ static void __init do_add_efi_memmap(void) e820_type =E820_RESERVED ;break ; } -e820_add_region (start, size, e820_type); +e820_add_limit_region (start, size, e820_type); }sanitize_e820_map (e820.map,ARRAY_SIZE (e820.map), &e820.nr_map); }
@@ -448,6 +455,8 @@ void __init efi_free_boot_services(void) md->type != EFI_BOOT_SERVICES_DATA)continue ; +e820_adjust_region (&start, &size); +/* Could not reserve boot area */ if (!size)continue ;
Signature · 1 line
1.8.0
Quoted 14 lines · Wen Congyang
arch/x86/platform/efi/efi.c +2
-2@@ -314,10 +314,17 @@ static void __init do_add_efi_memmap(void)int e820_type;switch (md->type) { -case EFI_LOADER_CODE : -case EFI_LOADER_DATA :case EFI_BOOT_SERVICES_CODE :case EFI_BOOT_SERVICES_DATA : +/* EFI_BOOT_SERVICES_{CODE,DATA} needs to be mapped */ +if (md->attribute &EFI_MEMORY_WB )
arch/x86/platform/efi/efi.c static void __init do_add_efi_memmap(void) · line 330
Quoted 10 lines
arch/x86/platform/efi/efi.c +7
-0+ e820_type =E820_RAM ; + else + e820_type =E820_RESERVED ; +e820_add_region (start, size, e820_type); +continue ; +case EFI_LOADER_CODE : +case EFI_LOADER_DATA :case EFI_CONVENTIONAL_MEMORY :if (md->attribute &EFI_MEMORY_WB ) e820_type =E820_RAM ;
This chunk seems to cause one of my EFI machines to crash. If I include EFI_LOADER_{CODE,DATA} in the same clause as EFI_BOOT_SERVICES* things work. I'm not sure why that is since the e820_type is E820_RAM.
Maybe I need to use memmap= too when booting?