Skip to content

Commit db227c1

Browse files
ardbiesheuvelRussell King
authored andcommitted
ARM: 8985/1: efi/decompressor: deal with HYP mode boot gracefully
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 makes HYP mode inaccessible to the operating system. 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 carry on executing at HYP. We do need to ensure that we disable the MMU at HYP before entering the kernel proper. - 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 as usual, so that we can return to HYP mode before handing over to the kernel proper. Tested-by: Heinrich Schuchardt <[email protected]> Signed-off-by: Ard Biesheuvel <[email protected]> Signed-off-by: Russell King <[email protected]>
1 parent 39c3e30 commit db227c1

File tree

1 file changed

+62
-0
lines changed
  • arch/arm/boot/compressed

1 file changed

+62
-0
lines changed

arch/arm/boot/compressed/head.S

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,7 +1410,11 @@ memdump: mov r12, r0
14101410
__hyp_reentry_vectors:
14111411
W(b) . @ reset
14121412
W(b) . @ undef
1413+
#ifdef CONFIG_EFI_STUB
1414+
W(b) __enter_kernel_from_hyp @ hvc from HYP
1415+
#else
14131416
W(b) . @ svc
1417+
#endif
14141418
W(b) . @ pabort
14151419
W(b) . @ dabort
14161420
W(b) __enter_kernel @ hyp
@@ -1429,14 +1433,72 @@ __enter_kernel:
14291433
reloc_code_end:
14301434

14311435
#ifdef CONFIG_EFI_STUB
1436+
__enter_kernel_from_hyp:
1437+
mrc p15, 4, r0, c1, c0, 0 @ read HSCTLR
1438+
bic r0, r0, #0x5 @ disable MMU and caches
1439+
mcr p15, 4, r0, c1, c0, 0 @ write HSCTLR
1440+
isb
1441+
b __enter_kernel
1442+
14321443
ENTRY(efi_enter_kernel)
14331444
mov r4, r0 @ preserve image base
14341445
mov r8, r1 @ preserve DT pointer
14351446

1447+
ARM( adrl r0, call_cache_fn )
1448+
THUMB( adr r0, call_cache_fn )
1449+
adr r1, 0f @ clean the region of code we
1450+
bl cache_clean_flush @ may run with the MMU off
1451+
1452+
#ifdef CONFIG_ARM_VIRT_EXT
1453+
@
1454+
@ The EFI spec does not support booting on ARM in HYP mode,
1455+
@ since it mandates that the MMU and caches are on, with all
1456+
@ 32-bit addressable DRAM mapped 1:1 using short descriptors.
1457+
@
1458+
@ While the EDK2 reference implementation adheres to this,
1459+
@ U-Boot might decide to enter the EFI stub in HYP mode
1460+
@ anyway, with the MMU and caches either on or off.
1461+
@
1462+
mrs r0, cpsr @ get the current mode
1463+
msr spsr_cxsf, r0 @ record boot mode
1464+
and r0, r0, #MODE_MASK @ are we running in HYP mode?
1465+
cmp r0, #HYP_MODE
1466+
bne .Lefi_svc
1467+
1468+
mrc p15, 4, r1, c1, c0, 0 @ read HSCTLR
1469+
tst r1, #0x1 @ MMU enabled at HYP?
1470+
beq 1f
1471+
1472+
@
1473+
@ When running in HYP mode with the caches on, we're better
1474+
@ off just carrying on using the cached 1:1 mapping that the
1475+
@ firmware provided. Set up the HYP vectors so HVC instructions
1476+
@ issued from HYP mode take us to the correct handler code. We
1477+
@ will disable the MMU before jumping to the kernel proper.
1478+
@
1479+
adr r0, __hyp_reentry_vectors
1480+
mcr p15, 4, r0, c12, c0, 0 @ set HYP vector base (HVBAR)
1481+
isb
1482+
b .Lefi_hyp
1483+
1484+
@
1485+
@ When running in HYP mode with the caches off, we need to drop
1486+
@ into SVC mode now, and let the decompressor set up its cached
1487+
@ 1:1 mapping as usual.
1488+
@
1489+
1: mov r9, r4 @ preserve image base
1490+
bl __hyp_stub_install @ install HYP stub vectors
1491+
safe_svcmode_maskall r1 @ drop to SVC mode
1492+
msr spsr_cxsf, r0 @ record boot mode
1493+
orr r4, r9, #1 @ restore image base and set LSB
1494+
b .Lefi_hyp
1495+
.Lefi_svc:
1496+
#endif
14361497
mrc p15, 0, r0, c1, c0, 0 @ read SCTLR
14371498
tst r0, #0x1 @ MMU enabled?
14381499
orreq r4, r4, #1 @ set LSB if not
14391500

1501+
.Lefi_hyp:
14401502
mov r0, r8 @ DT start
14411503
add r1, r8, r2 @ DT end
14421504
bl cache_clean_flush

0 commit comments

Comments
 (0)