Commit c7225494 authored by Ard Biesheuvel's avatar Ard Biesheuvel

efi/arm: Work around missing cache maintenance in decompressor handover

The EFI stub executes within the context of the zImage as it was
loaded by the firmware, which means it is treated as an ordinary
PE/COFF executable, which is loaded into memory, and cleaned to
the PoU to ensure that it can be executed safely while the MMU
and caches are on.

When the EFI stub hands over to the decompressor, we clean the caches
by set/way and disable the MMU and D-cache, to comply with the Linux
boot protocol for ARM. However, cache maintenance by set/way is not
sufficient to ensure that subsequent instruction fetches and data
accesses done with the MMU off see the correct data. This means that
proceeding as we do currently is not safe, especially since we also
perform data accesses with the MMU off, from a literal pool as well as
the stack.

So let's kick this can down the road a bit, and jump into the relocated
zImage before disabling the caches. This removes the requirement to
perform any by-VA cache maintenance on the original PE/COFF executable,
but it does require that the relocated zImage is cleaned to the PoC,
which is currently not the case. This will be addressed in a subsequent
patch.
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent bb6d3fb3
...@@ -1461,6 +1461,17 @@ ENTRY(efi_stub_entry) ...@@ -1461,6 +1461,17 @@ ENTRY(efi_stub_entry)
@ Preserve return value of efi_entry() in r4 @ Preserve return value of efi_entry() in r4
mov r4, r0 mov r4, r0
bl cache_clean_flush bl cache_clean_flush
@ The PE/COFF loader might not have cleaned the code we are
@ running beyond the PoU, and so calling cache_off below from
@ inside the PE/COFF loader allocated region is unsafe. Let's
@ assume our own zImage relocation code did a better job, and
@ jump into its version of this routine before proceeding.
ldr r0, [sp] @ relocated zImage
ldr r1, .Ljmp
sub r1, r0, r1
mov pc, r1 @ no mode switch
0:
bl cache_off bl cache_off
@ Set parameters for booting zImage according to boot protocol @ Set parameters for booting zImage according to boot protocol
...@@ -1469,18 +1480,15 @@ ENTRY(efi_stub_entry) ...@@ -1469,18 +1480,15 @@ ENTRY(efi_stub_entry)
mov r0, #0 mov r0, #0
mov r1, #0xFFFFFFFF mov r1, #0xFFFFFFFF
mov r2, r4 mov r2, r4
b __efi_start
@ Branch to (possibly) relocated zImage that is in [sp]
ldr lr, [sp]
ldr ip, =start_offset
add lr, lr, ip
mov pc, lr @ no mode switch
efi_load_fail: efi_load_fail:
@ Return EFI_LOAD_ERROR to EFI firmware on error. @ Return EFI_LOAD_ERROR to EFI firmware on error.
ldr r0, =0x80000001 ldr r0, =0x80000001
ldmfd sp!, {ip, pc} ldmfd sp!, {ip, pc}
ENDPROC(efi_stub_entry) ENDPROC(efi_stub_entry)
.align 2
.Ljmp: .long start - 0b
#endif #endif
.align .align
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment