Skip to content

Commit 29f9007

Browse files
Ard BiesheuvelRussell King
authored andcommitted
efi/libstub: arm: omit sorting of the UEFI memory map
ARM shares its EFI stub implementation with arm64, which has some special handling in the virtual remapping code to a) make sure that we can map everything even if the OS executes with 64k page size, and b) make sure that adjacent regions with the same attributes are not reordered or moved apart in memory. The latter is a workaround for a 'feature' that was shortly recommended by UEFI spec v2.5, but deprecated shortly after, due to the fact that it broke many OS installers, including non-Linux ones, and it was never widely implemented for ARM systems. Before implementing b), the arm64 code simply rounded up all regions to 64 KB granularity, but given that that results in moving adjacent regions apart, it had to be refined when b) was implemented. The adjacency check requires a sort() pass, due to the fact that the UEFI spec does not mandate any ordering, and the inclusion of the lib/sort.c code into the ARM EFI stub is causing some trouble with the decompressor build due to the fact that its EXPORT_SYMBOL() call triggers the creation of ksymtab/kcrctab sections. So let's simply do away with the adjacency check for ARM, and simply put all UEFI runtime regions together if they have the same memory attributes. This is guaranteed to work, given that ARM only supports 4 KB pages, and allows us to remove the sort() call entirely. Signed-off-by: Ard Biesheuvel <[email protected]> Acked-by: Will Deacon <[email protected]> Tested-by: Jeffy Chen <[email protected]> Tested-by: Gregory CLEMENT <[email protected]> Tested-by: Matthias Brugger <[email protected]> Signed-off-by: Russell King <[email protected]>
1 parent 1cce91d commit 29f9007

File tree

2 files changed

+8
-5
lines changed

2 files changed

+8
-5
lines changed

drivers/firmware/efi/libstub/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,14 @@ lib-y := efi-stub-helper.o gop.o secureboot.o
3333
lib-$(CONFIG_RESET_ATTACK_MITIGATION) += tpm.o
3434

3535
# include the stub's generic dependencies from lib/ when building for ARM/arm64
36-
arm-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c sort.c
36+
arm-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c
37+
arm-deps-$(CONFIG_ARM64) += sort.c
3738

3839
$(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
3940
$(call if_changed_rule,cc_o_c)
4041

4142
lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o random.o \
42-
$(patsubst %.c,lib-%.o,$(arm-deps))
43+
$(patsubst %.c,lib-%.o,$(arm-deps-y))
4344

4445
lib-$(CONFIG_ARM) += arm32-stub.o
4546
lib-$(CONFIG_ARM64) += arm64-stub.o
@@ -90,5 +91,4 @@ quiet_cmd_stubcopy = STUBCPY $@
9091
# explicitly by the decompressor linker script.
9192
#
9293
STUBCOPY_FLAGS-$(CONFIG_ARM) += --rename-section .data=.data.efistub
93-
STUBCOPY_RM-$(CONFIG_ARM) += -R ___ksymtab+sort -R ___kcrctab+sort
9494
STUBCOPY_RELOC-$(CONFIG_ARM) := R_ARM_ABS

drivers/firmware/efi/libstub/arm-stub.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,9 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
349349
* The easiest way to find adjacent regions is to sort the memory map
350350
* before traversing it.
351351
*/
352-
sort(memory_map, map_size / desc_size, desc_size, cmp_mem_desc, NULL);
352+
if (IS_ENABLED(CONFIG_ARM64))
353+
sort(memory_map, map_size / desc_size, desc_size, cmp_mem_desc,
354+
NULL);
353355

354356
for (l = 0; l < map_size; l += desc_size, prev = in) {
355357
u64 paddr, size;
@@ -366,7 +368,8 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
366368
* a 4k page size kernel to kexec a 64k page size kernel and
367369
* vice versa.
368370
*/
369-
if (!regions_are_adjacent(prev, in) ||
371+
if ((IS_ENABLED(CONFIG_ARM64) &&
372+
!regions_are_adjacent(prev, in)) ||
370373
!regions_have_compatible_memory_type_attrs(prev, in)) {
371374

372375
paddr = round_down(in->phys_addr, SZ_64K);

0 commit comments

Comments
 (0)