Skip to content

Commit d0f9ca9

Browse files
committed
ARM: decompressor: run decompressor in place if loaded via UEFI
The decompressor can load from anywhere in memory, and the only reason the EFI stub code relocates it is to ensure it appears within the first 128 MiB of memory, so that the uncompressed kernel ends up at the right offset in memory. We can short circuit this, and simply jump into the decompressor startup code at the point where it knows where the base of memory lives. This also means there is no need to disable the MMU and caches, create new page tables and re-enable them. Signed-off-by: Ard Biesheuvel <[email protected]> Reviewed-by: Nicolas Pitre <[email protected]>
1 parent 35d57d1 commit d0f9ca9

File tree

2 files changed

+20
-64
lines changed

2 files changed

+20
-64
lines changed

arch/arm/boot/compressed/head.S

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,37 +1430,26 @@ reloc_code_end:
14301430

14311431
#ifdef CONFIG_EFI_STUB
14321432
ENTRY(efi_enter_kernel)
1433-
mov r7, r0 @ preserve image base
1434-
mov r4, r1 @ preserve DT pointer
1433+
mov r4, r0 @ preserve image base
1434+
mov r8, r1 @ preserve DT pointer
14351435

1436-
mov r0, r4 @ DT start
1437-
add r1, r4, r2 @ DT end
1438-
bl cache_clean_flush
1436+
mrc p15, 0, r0, c1, c0, 0 @ read SCTLR
1437+
tst r0, #0x1 @ MMU enabled?
1438+
orreq r4, r4, #1 @ set LSB if not
14391439

1440-
mov r0, r7 @ relocated zImage
1441-
ldr r1, =_edata @ size of zImage
1442-
add r1, r1, r0 @ end of zImage
1440+
mov r0, r8 @ DT start
1441+
add r1, r8, r2 @ DT end
14431442
bl cache_clean_flush
14441443

1445-
@ The PE/COFF loader might not have cleaned the code we are
1446-
@ running beyond the PoU, and so calling cache_off below from
1447-
@ inside the PE/COFF loader allocated region is unsafe unless
1448-
@ we explicitly clean it to the PoC.
1449-
adr r0, call_cache_fn @ region of code we will
1450-
adr r1, 0f @ run with MMU off
1451-
bl cache_clean_flush
1452-
bl cache_off
1444+
adr r0, 0f @ switch to our stack
1445+
ldr sp, [r0]
1446+
add sp, sp, r0
14531447

1454-
@ Set parameters for booting zImage according to boot protocol
1455-
@ put FDT address in r2, it was returned by efi_entry()
1456-
@ r1 is the machine type, and r0 needs to be 0
1457-
mov r0, #0
1458-
mov r1, #0xFFFFFFFF
1459-
mov r2, r4
1460-
add r7, r7, #(__efi_start - start)
1461-
mov pc, r7 @ no mode switch
1448+
mov r5, #0 @ appended DTB size
1449+
mov r7, #0xFFFFFFFF @ machine ID
1450+
b wont_overwrite
14621451
ENDPROC(efi_enter_kernel)
1463-
0:
1452+
0: .long .L_user_stack_end - .
14641453
#endif
14651454

14661455
.align

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

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -199,14 +199,8 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
199199
unsigned long kernel_base;
200200
efi_status_t status;
201201

202-
/*
203-
* Verify that the DRAM base address is compatible with the ARM
204-
* boot protocol, which determines the base of DRAM by masking
205-
* off the low 27 bits of the address at which the zImage is
206-
* loaded. These assumptions are made by the decompressor,
207-
* before any memory map is available.
208-
*/
209-
kernel_base = round_up(dram_base, SZ_128M);
202+
/* use a 16 MiB aligned base for the decompressed kernel */
203+
kernel_base = round_up(dram_base, SZ_16M) + TEXT_OFFSET;
210204

211205
/*
212206
* Note that some platforms (notably, the Raspberry Pi 2) put
@@ -215,41 +209,14 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
215209
* base of the kernel image is only partially used at the moment.
216210
* (Up to 5 pages are used for the swapper page tables)
217211
*/
218-
kernel_base += TEXT_OFFSET - 5 * PAGE_SIZE;
219-
220-
status = reserve_kernel_base(kernel_base, reserve_addr, reserve_size);
212+
status = reserve_kernel_base(kernel_base - 5 * PAGE_SIZE, reserve_addr,
213+
reserve_size);
221214
if (status != EFI_SUCCESS) {
222215
pr_efi_err("Unable to allocate memory for uncompressed kernel.\n");
223216
return status;
224217
}
225218

226-
/*
227-
* Relocate the zImage, so that it appears in the lowest 128 MB
228-
* memory window.
229-
*/
230-
*image_addr = (unsigned long)image->image_base;
231-
*image_size = image->image_size;
232-
status = efi_relocate_kernel(image_addr, *image_size, *image_size,
233-
kernel_base + MAX_UNCOMP_KERNEL_SIZE, 0, 0);
234-
if (status != EFI_SUCCESS) {
235-
pr_efi_err("Failed to relocate kernel.\n");
236-
efi_free(*reserve_size, *reserve_addr);
237-
*reserve_size = 0;
238-
return status;
239-
}
240-
241-
/*
242-
* Check to see if we were able to allocate memory low enough
243-
* in memory. The kernel determines the base of DRAM from the
244-
* address at which the zImage is loaded.
245-
*/
246-
if (*image_addr + *image_size > dram_base + ZIMAGE_OFFSET_LIMIT) {
247-
pr_efi_err("Failed to relocate kernel, no low memory available.\n");
248-
efi_free(*reserve_size, *reserve_addr);
249-
*reserve_size = 0;
250-
efi_free(*image_size, *image_addr);
251-
*image_size = 0;
252-
return EFI_LOAD_ERROR;
253-
}
219+
*image_addr = kernel_base;
220+
*image_size = 0;
254221
return EFI_SUCCESS;
255222
}

0 commit comments

Comments
 (0)