Skip to content

Commit 005e126

Browse files
ardbiesheuvelwilldeacon
authored andcommitted
arm64: head: record CPU boot mode after enabling the MMU
In order to avoid having to touch memory with the MMU and caches disabled, and therefore having to invalidate it from the caches explicitly, just defer storing the value until after the MMU has been turned on, unless we are giving up with an error. While at it, move the associated variable definitions into C code. Signed-off-by: Ard Biesheuvel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 6495b9b commit 005e126

File tree

3 files changed

+23
-39
lines changed

3 files changed

+23
-39
lines changed

arch/arm64/kernel/head.S

Lines changed: 13 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
* primary lowlevel boot path:
8383
*
8484
* Register Scope Purpose
85+
* x20 primary_entry() .. __primary_switch() CPU boot mode
8586
* x21 primary_entry() .. start_kernel() FDT pointer passed at boot in x0
8687
* x22 create_idmap() .. start_kernel() ID map VA of the DT blob
8788
* x23 primary_entry() .. start_kernel() physical misalignment/KASLR offset
@@ -91,9 +92,9 @@
9192
SYM_CODE_START(primary_entry)
9293
bl preserve_boot_args
9394
bl init_kernel_el // w0=cpu_boot_mode
95+
mov x20, x0
9496
adrp x23, __PHYS_OFFSET
9597
and x23, x23, MIN_KIMG_ALIGN - 1 // KASLR offset, defaults to 0
96-
bl set_cpu_boot_mode_flag
9798
bl create_idmap
9899

99100
/*
@@ -429,6 +430,9 @@ SYM_FUNC_START_LOCAL(__primary_switched)
429430
sub x4, x4, x0 // the kernel virtual and
430431
str_l x4, kimage_voffset, x5 // physical mappings
431432

433+
mov x0, x20
434+
bl set_cpu_boot_mode_flag
435+
432436
// Clear BSS
433437
adr_l x0, __bss_start
434438
mov x1, xzr
@@ -454,6 +458,7 @@ SYM_FUNC_START_LOCAL(__primary_switched)
454458
ret // to __primary_switch()
455459
0:
456460
#endif
461+
mov x0, x20
457462
bl switch_to_vhe // Prefer VHE if possible
458463
ldp x29, x30, [sp], #16
459464
bl start_kernel
@@ -553,52 +558,21 @@ SYM_FUNC_START_LOCAL(set_cpu_boot_mode_flag)
553558
b.ne 1f
554559
add x1, x1, #4
555560
1: str w0, [x1] // Save CPU boot mode
556-
dmb sy
557-
dc ivac, x1 // Invalidate potentially stale cache line
558561
ret
559562
SYM_FUNC_END(set_cpu_boot_mode_flag)
560563

561-
/*
562-
* These values are written with the MMU off, but read with the MMU on.
563-
* Writers will invalidate the corresponding address, discarding up to a
564-
* 'Cache Writeback Granule' (CWG) worth of data. The linker script ensures
565-
* sufficient alignment that the CWG doesn't overlap another section.
566-
*/
567-
.pushsection ".mmuoff.data.write", "aw"
568-
/*
569-
* We need to find out the CPU boot mode long after boot, so we need to
570-
* store it in a writable variable.
571-
*
572-
* This is not in .bss, because we set it sufficiently early that the boot-time
573-
* zeroing of .bss would clobber it.
574-
*/
575-
SYM_DATA_START(__boot_cpu_mode)
576-
.long BOOT_CPU_MODE_EL2
577-
.long BOOT_CPU_MODE_EL1
578-
SYM_DATA_END(__boot_cpu_mode)
579-
/*
580-
* The booting CPU updates the failed status @__early_cpu_boot_status,
581-
* with MMU turned off.
582-
*/
583-
SYM_DATA_START(__early_cpu_boot_status)
584-
.quad 0
585-
SYM_DATA_END(__early_cpu_boot_status)
586-
587-
.popsection
588-
589564
/*
590565
* This provides a "holding pen" for platforms to hold all secondary
591566
* cores are held until we're ready for them to initialise.
592567
*/
593568
SYM_FUNC_START(secondary_holding_pen)
594569
bl init_kernel_el // w0=cpu_boot_mode
595-
bl set_cpu_boot_mode_flag
596-
mrs x0, mpidr_el1
570+
mrs x2, mpidr_el1
597571
mov_q x1, MPIDR_HWID_BITMASK
598-
and x0, x0, x1
572+
and x2, x2, x1
599573
adr_l x3, secondary_holding_pen_release
600574
pen: ldr x4, [x3]
601-
cmp x4, x0
575+
cmp x4, x2
602576
b.eq secondary_startup
603577
wfe
604578
b pen
@@ -610,14 +584,14 @@ SYM_FUNC_END(secondary_holding_pen)
610584
*/
611585
SYM_FUNC_START(secondary_entry)
612586
bl init_kernel_el // w0=cpu_boot_mode
613-
bl set_cpu_boot_mode_flag
614587
b secondary_startup
615588
SYM_FUNC_END(secondary_entry)
616589

617590
SYM_FUNC_START_LOCAL(secondary_startup)
618591
/*
619592
* Common entry point for secondary CPUs.
620593
*/
594+
mov x20, x0 // preserve boot mode
621595
bl switch_to_vhe
622596
bl __cpu_secondary_check52bitva
623597
bl __cpu_setup // initialise processor
@@ -629,6 +603,9 @@ SYM_FUNC_START_LOCAL(secondary_startup)
629603
SYM_FUNC_END(secondary_startup)
630604

631605
SYM_FUNC_START_LOCAL(__secondary_switched)
606+
mov x0, x20
607+
bl set_cpu_boot_mode_flag
608+
str_l xzr, __early_cpu_boot_status, x3
632609
adr_l x5, vectors
633610
msr vbar_el1, x5
634611
isb
@@ -691,7 +668,6 @@ SYM_FUNC_START(__enable_mmu)
691668
b.lt __no_granule_support
692669
cmp x3, #ID_AA64MMFR0_TGRAN_SUPPORTED_MAX
693670
b.gt __no_granule_support
694-
update_early_cpu_boot_status 0, x3, x4
695671
phys_to_ttbr x2, x2
696672
msr ttbr0_el1, x2 // load TTBR0
697673
load_ttbr1 x1, x1, x3

arch/arm64/kernel/hyp-stub.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,11 @@ SYM_FUNC_END(__hyp_reset_vectors)
223223

224224
/*
225225
* Entry point to switch to VHE if deemed capable
226+
*
227+
* w0: boot mode, as returned by init_kernel_el()
226228
*/
227229
SYM_FUNC_START(switch_to_vhe)
228230
// Need to have booted at EL2
229-
adr_l x1, __boot_cpu_mode
230-
ldr w0, [x1]
231231
cmp w0, #BOOT_CPU_MODE_EL2
232232
b.ne 1f
233233

arch/arm64/mm/mmu.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ EXPORT_SYMBOL(kimage_vaddr);
5656
u64 kimage_voffset __ro_after_init;
5757
EXPORT_SYMBOL(kimage_voffset);
5858

59+
u32 __boot_cpu_mode[] = { BOOT_CPU_MODE_EL2, BOOT_CPU_MODE_EL1 };
60+
61+
/*
62+
* The booting CPU updates the failed status @__early_cpu_boot_status,
63+
* with MMU turned off.
64+
*/
65+
long __section(".mmuoff.data.write") __early_cpu_boot_status;
66+
5967
/*
6068
* Empty_zero_page is a special page that is used for zero-initialized data
6169
* and COW.

0 commit comments

Comments
 (0)