All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] arm64: mm: fix booting with 52-bit address space
@ 2022-07-01 11:10 Ard Biesheuvel
  2022-07-01 15:41 ` Will Deacon
  0 siblings, 1 reply; 2+ messages in thread
From: Ard Biesheuvel @ 2022-07-01 11:10 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Ard Biesheuvel, Will Deacon, Anshuman Khandual, Mark Rutland, Joey Gouly

Joey reports that booting 52-bit VA capable builds on 52-bit VA capable
CPUs is broken since commit 0d9b1ffefabe ("arm64: mm: make vabits_actual
a build time constant if possible"). This is due to the fact that the
primary CPU reads the vabits_actual variable before it has been
assigned.

The reason for deferring the assignment of vabits_actual was that we try
to perform as few stores to memory as we can with the MMU and caches
off, due to the cache coherency issues it creates.

Since __cpu_setup() [which is where the read of vabits_actual occurs] is
also called on the secondary boot path, we cannot just read the CPU ID
registers directly, given that the size of the VA space is decided by
the capabilities of the primary CPU. So let's read vabits_actual only on
the secondary boot path, and read the CPU ID registers directly on the
primary boot path, by making it a function parameter of __cpu_setup().

To ensure that all users of vabits_actual (including kasan_early_init())
observe the correct value, move the assignment of vabits_actual back
into asm code, but still defer it to after the MMU and caches have been
enabled.

Cc: Will Deacon <will@kernel.org>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Fixes: 0d9b1ffefabe ("arm64: mm: make vabits_actual a build time constant if possible")
Reported-by: Joey Gouly <joey.gouly@arm.com>
Co-developed-by: Joey Gouly <joey.gouly@arm.com>
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
v3: fix KASAN too

 arch/arm64/kernel/head.S | 18 ++++++++++++++++++
 arch/arm64/mm/init.c     | 15 +--------------
 arch/arm64/mm/proc.S     |  5 +++--
 3 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index c300b43659dc..ae0a9e44ca19 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -82,6 +82,7 @@
 	 *  x22        create_idmap() .. start_kernel()         ID map VA of the DT blob
 	 *  x23        primary_entry() .. start_kernel()        physical misalignment/KASLR offset
 	 *  x24        __primary_switch()                       linear map KASLR seed
+	 *  x25        primary_entry() .. start_kernel()        supported VA size
 	 *  x28        create_idmap()                           callee preserved temp register
 	 */
 SYM_CODE_START(primary_entry)
@@ -96,6 +97,14 @@ SYM_CODE_START(primary_entry)
 	 * On return, the CPU will be ready for the MMU to be turned on and
 	 * the TCR will have been set.
 	 */
+#if VA_BITS > 48
+	mrs_s	x0, SYS_ID_AA64MMFR2_EL1
+	tst	x0, #0xf << ID_AA64MMFR2_LVA_SHIFT
+	mov	x0, #VA_BITS
+	mov	x25, #VA_BITS_MIN
+	csel	x25, x25, x0, eq
+	mov	x0, x25
+#endif
 	bl	__cpu_setup			// initialise processor
 	b	__primary_switch
 SYM_CODE_END(primary_entry)
@@ -434,6 +443,12 @@ SYM_FUNC_START_LOCAL(__primary_switched)
 	bl	__pi_memset
 	dsb	ishst				// Make zero page visible to PTW
 
+#if VA_BITS > 48
+	adr_l	x8, vabits_actual		// Set this early so KASAN early init
+	str	x25, [x8]			// ... observes the correct value
+	dc	civac, x8			// Make visible to booting secondaries
+#endif
+
 #ifdef CONFIG_RANDOMIZE_BASE
 	adrp	x5, memstart_offset_seed	// Save KASLR linear map seed
 	strh	w24, [x5, :lo12:memstart_offset_seed]
@@ -579,6 +594,9 @@ SYM_FUNC_START_LOCAL(secondary_startup)
 	mov	x20, x0				// preserve boot mode
 	bl	switch_to_vhe
 	bl	__cpu_secondary_check52bitva
+#if VA_BITS > 48
+	ldr_l	x0, vabits_actual
+#endif
 	bl	__cpu_setup			// initialise processor
 	adrp	x1, swapper_pg_dir
 	adrp	x2, idmap_pg_dir
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 1faa6760895e..339ee84e5a61 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -265,20 +265,7 @@ early_param("mem", early_mem);
 
 void __init arm64_memblock_init(void)
 {
-	s64 linear_region_size;
-
-#if VA_BITS > 48
-	if (cpuid_feature_extract_unsigned_field(
-				read_sysreg_s(SYS_ID_AA64MMFR2_EL1),
-				ID_AA64MMFR2_LVA_SHIFT))
-		vabits_actual = VA_BITS;
-
-	/* make the variable visible to secondaries with the MMU off */
-	dcache_clean_inval_poc((u64)&vabits_actual,
-			       (u64)&vabits_actual + sizeof(vabits_actual));
-#endif
-
-	linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
+	s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
 
 	/*
 	 * Corner case: 52-bit VA capable systems running KVM in nVHE mode may
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 493b8ffc9be5..7837a69524c5 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -398,6 +398,8 @@ SYM_FUNC_END(idmap_kpti_install_ng_mappings)
  *
  *	Initialise the processor for turning the MMU on.
  *
+ * Input:
+ *	x0 - actual number of VA bits (ignored unless VA_BITS > 48)
  * Output:
  *	Return in x0 the value of the SCTLR_EL1 register.
  */
@@ -467,8 +469,7 @@ SYM_FUNC_START(__cpu_setup)
 	tcr_clear_errata_bits tcr, x9, x5
 
 #ifdef CONFIG_ARM64_VA_BITS_52
-	ldr_l		x9, vabits_actual
-	sub		x9, xzr, x9
+	sub		x9, xzr, x0
 	add		x9, x9, #64
 	tcr_set_t1sz	tcr, x9
 #else
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v3] arm64: mm: fix booting with 52-bit address space
  2022-07-01 11:10 [PATCH v3] arm64: mm: fix booting with 52-bit address space Ard Biesheuvel
@ 2022-07-01 15:41 ` Will Deacon
  0 siblings, 0 replies; 2+ messages in thread
From: Will Deacon @ 2022-07-01 15:41 UTC (permalink / raw)
  To: linux-arm-kernel, Ard Biesheuvel
  Cc: catalin.marinas, kernel-team, Will Deacon, Mark Rutland,
	Anshuman Khandual, Joey Gouly

On Fri, 1 Jul 2022 13:10:45 +0200, Ard Biesheuvel wrote:
> Joey reports that booting 52-bit VA capable builds on 52-bit VA capable
> CPUs is broken since commit 0d9b1ffefabe ("arm64: mm: make vabits_actual
> a build time constant if possible"). This is due to the fact that the
> primary CPU reads the vabits_actual variable before it has been
> assigned.
> 
> The reason for deferring the assignment of vabits_actual was that we try
> to perform as few stores to memory as we can with the MMU and caches
> off, due to the cache coherency issues it creates.
> 
> [...]

Applied to arm64 (for-next/boot), thanks!

[1/1] arm64: mm: fix booting with 52-bit address space
      https://git.kernel.org/arm64/c/0aaa68532e9d

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-07-01 15:42 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-01 11:10 [PATCH v3] arm64: mm: fix booting with 52-bit address space Ard Biesheuvel
2022-07-01 15:41 ` Will Deacon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.