efi_loader: Reserve unaccessible memory
PATCH 1/1 efi_loader: Reserve unaccessible memory
On some systems, not all RAM may be usable within U-Boot. Maybe the memory maps are incomplete, maybe it's used as workaround for broken DMA. But whatever the reason may be, a platform can say that it does not wish to have its RAM accessed above a certain address by defining board_get_usable_ram_top().
In the efi_loader world, we ignored that hint, mostly because very few boards actually have real restrictions around this.
So let's honor the board's wish to not access high addresses during boot time. The best way to do so is by indicating the respective pages as "allocated by firmware". That way, Operating Systems will still use the pages after boot, but before boot no allocation will use them.
--- include/common.h | 11 +++++++++++ lib/efi_loader/efi_memory.c | 9 +++++++++ 2 files changed, 20 insertions(+)
include/common.h +11 -0
@@ -106,6 +106,17 @@ int mdm_init(void);void board_show_dram (phys_size_t size);/** +* Get the uppermost pointer that is valid to access +* +* Some systems may not map all of their address space. This function allows +* boards to indicate what their highest support pointer value is for DRAM +* access. +* +* @param total_size Size of U-Boot (unused?) +*/ +ulong board_get_usable_ram_top (ulong total_size); + +/** * arch_fixup_fdt() - Write arch-specific information to fdt * * Defined in arch/$(ARCH)/lib/bootm-fdt.c
lib/efi_loader/efi_memory.c +9 -0
@@ -551,6 +551,7 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,__weak void efi_add_known_memory (void ) { +u64 ram_top =board_get_usable_ram_top (0 ) & ~EFI_PAGE_MASK ;int i;/* Add RAM */
@@ -570,6 +571,14 @@ __weak void efi_add_known_memory(void)efi_add_memory_map (ram_start, pages,EFI_CONVENTIONAL_MEMORY , false); } + +/* Reserve memory above ram_top, as that may not be mapped */ +if ((ram_top >= ram_start) && (ram_top < ram_end)) { + pages = (ram_end - ram_top) >>EFI_PAGE_SHIFT ; + +efi_add_memory_map (ram_top, pages, +EFI_BOOT_SERVICES_DATA , true); + } } }
Signature · 1 line
2.12.3
PATCH 1/1 efi_loader: Reserve unaccessible memory
Quoted 56 lines · Alexander Graf
On some systems, not all RAM may be usable within U-Boot. Maybe the memory maps are incomplete, maybe it's used as workaround for broken DMA. But whatever the reason may be, a platform can say that it does not wish to have its RAM accessed above a certain address by defining
board_get_usable_ram_top().In the
efi_loaderworld, we ignored that hint, mostly because very few boards actually have real restrictions around this.So let's honor the board's wish to not access high addresses during boot time. The best way to do so is by indicating the respective pages as "allocated by firmware". That way, Operating Systems will still use the pages after boot, but before boot no allocation will use them.
Reported-by Baruch Siach <[email protected]>Signed-off-by Alexander Graf <[email protected]>--- include/common.h | 11 +++++++++++ lib/efi_loader/efi_memory.c | 9 +++++++++ 2 files changed, 20 insertions(+)include/common.h +11
-0@@ -106,6 +106,17 @@ int mdm_init(void);void board_show_dram (phys_size_t size);/** +* Get the uppermost pointer that is valid to access +* +* Some systems may not map all of their address space. This function allows +* boards to indicate what their highest support pointer value is for DRAM +* access. +* +* @param total_size Size of U-Boot (unused?) +*/ +ulong board_get_usable_ram_top (ulong total_size); + +/** * arch_fixup_fdt() - Write arch-specific information to fdt * * Defined in arch/$(ARCH)/lib/bootm-fdt.c lib/efi_loader/efi_memory.c +1
-0@@ -551,6 +551,7 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,__weak void efi_add_known_memory (void ) { +u64 ram_top =board_get_usable_ram_top (0 ) & ~EFI_PAGE_MASK ;int i;/* Add RAM */
lib/efi_loader/efi_memory.c __weak void efi_add_known_memory(void) · line 577
Quoted 7 lines
lib/efi_loader/efi_memory.c +4
-0@@ -570,6 +571,14 @@ __weak void efi_add_known_memory(void)efi_add_memory_map (ram_start, pages,EFI_CONVENTIONAL_MEMORY , false); } + +/* Reserve memory above ram_top, as that may not be mapped */ +if ((ram_top >= ram_start) && (ram_top < ram_end)) { + pages = (ram_end - ram_top) >>EFI_PAGE_SHIFT ;
Please, do not assume that ram_end is page aligned. You could use the macro efi_size_in_pages() here. See
https://patchwork.ozlabs.org/patch/999522/
Best regards
Heinrich
Quoted 8 lines
lib/efi_loader/efi_memory.c +4
-0+ +efi_add_memory_map (ram_top, pages, +EFI_BOOT_SERVICES_DATA , true); + } } }
PATCH 1/1 efi_loader: Reserve unaccessible memory
Quoted 50 lines · Heinrich Schuchardt
Quoted 49 lines · Alexander Graf
On some systems, not all RAM may be usable within U-Boot. Maybe the memory maps are incomplete, maybe it's used as workaround for broken DMA. But whatever the reason may be, a platform can say that it does not wish to have its RAM accessed above a certain address by defining
board_get_usable_ram_top().In the
efi_loaderworld, we ignored that hint, mostly because very few boards actually have real restrictions around this.So let's honor the board's wish to not access high addresses during boot time. The best way to do so is by indicating the respective pages as "allocated by firmware". That way, Operating Systems will still use the pages after boot, but before boot no allocation will use them.
Reported-by Baruch Siach <[email protected]>Signed-off-by Alexander Graf <[email protected]>--- include/common.h | 11 +++++++++++ lib/efi_loader/efi_memory.c | 9 +++++++++ 2 files changed, 20 insertions(+)include/common.h +11
-0@@ -106,6 +106,17 @@ int mdm_init(void);void board_show_dram (phys_size_t size);/** +* Get the uppermost pointer that is valid to access +* +* Some systems may not map all of their address space. This function allows +* boards to indicate what their highest support pointer value is for DRAM +* access. +* +* @param total_size Size of U-Boot (unused?) +*/ +ulong board_get_usable_ram_top (ulong total_size); + +/** * arch_fixup_fdt() - Write arch-specific information to fdt * * Defined in arch/$(ARCH)/lib/bootm-fdt.c lib/efi_loader/efi_memory.c +0
-0@@ -551,6 +551,7 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
Quoted 3 lines
lib/efi_loader/efi_memory.c efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size, · line 554
Quoted 3 lines
lib/efi_loader/efi_memory.c +1
-0__weak void efi_add_known_memory (void ) { +u64 ram_top =board_get_usable_ram_top (0 ) & ~EFI_PAGE_MASK ;
^
Quoted 13 lines
lib/efi_loader/efi_memory.c __weak void efi_add_known_memory(void) · line 577
Quoted 11 lines
lib/efi_loader/efi_memory.c +4
-0int i;/* Add RAM */ @@ -570,6 +571,14 @@ __weak void efi_add_known_memory(void)efi_add_memory_map (ram_start, pages,EFI_CONVENTIONAL_MEMORY , false); } + +/* Reserve memory above ram_top, as that may not be mapped */ +if ((ram_top >= ram_start) && (ram_top < ram_end)) { + pages = (ram_end - ram_top) >>EFI_PAGE_SHIFT ;Please, do not assume that
ram_endis page aligned.
See above. I align it manually, no?
Alex
Quoted 17 lines
You could use the
macroefi_size_in_pages()here. See
https://patchwork.ozlabs.org/patch/999522/Best regards
Heinrich
Quoted 8 lines
lib/efi_loader/efi_memory.c +4
-0+ +efi_add_memory_map (ram_top, pages, +EFI_BOOT_SERVICES_DATA , true); + } } }