EFI on ARM only supports short descriptors, and given that it mandates that the MMU and caches are on, it is implied that booting in HYP mode is not supported. However, implementations of EFI exist (i.e., U-Boot) that ignore this requirement, which is not entirely unreasonable, given that it does not make a lot of sense to begin with. So let's make sure that we can deal with this condition gracefully. We already tolerate booting the EFI stub with the caches off (even though this violates the EFI spec as well), and so we should deal with HYP mode boot with MMU and caches either on or off. - When the MMU and caches are on, we can ignore the HYP stub altogether, since we can just use the existing mappings, and just branch into the decompressed kernel as usual after disabling MMU and caches. - When the MMU and caches are off, we have to drop to SVC mode so that we can set up the page tables using short descriptors. In this case, we need to install the HYP stub so that we can return to HYP mode when handing over to the kernel proper. Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx> --- arch/arm/boot/compressed/head.S | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index c79db44ba128..986db86ba334 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -1436,6 +1436,35 @@ ENTRY(efi_enter_kernel) mrc p15, 0, r0, c1, c0, 0 @ read SCTLR tst r0, #0x1 @ MMU enabled? orreq r4, r4, #1 @ set LSB if not +#ifdef CONFIG_ARM_VIRT_EXT + @ + @ The EFI spec does not support booting on ARM in HYP mode, + @ since it mandates that the MMU and caches are on, with all + @ 32-bit addressable DRAM mapped 1:1 using short descriptors. + @ While the EDK2 reference implementation adheres to this, + @ U-Boot might decide to enter the EFI stub in HYP mode anyway, + @ with the MMU and caches either on or off. + @ In the former case, we're better off just carrying on using + @ the cached 1:1 mapping that the firmware provided, and pretend + @ that we are in SVC mode as far as the decompressor is + @ concerned. However, if the caches are off, we need to drop + @ into SVC mode now, and let the decompressor set up its cached + @ 1:1 mapping as usual. + @ + mov r0, #SVC_MODE + msr spsr_cxsf, r0 @ record that we are in SVC mode + bne 1f @ skip HYP stub install if MMU is on + + mov r9, r4 @ preserve image base + bl __hyp_stub_install @ returns boot mode in r4 + cmp r4, #HYP_MODE @ did we boot in HYP? + bne 1f @ skip drop to SVC if we did not + + safe_svcmode_maskall r0 + msr spsr_cxsf, r4 @ record boot mode + mov r4, r9 @ restore image base +1: +#endif mov r0, r8 @ DT start add r1, r8, r2 @ DT end -- 2.26.2