linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] ARM/decompressor: deal with disabled CP15 barrier instructions
@ 2019-11-18 18:15 Ard Biesheuvel
  2019-11-18 18:15 ` [PATCH v2 1/2] ARM/decompressor: enable CP15 barrier instructions in v7 cache setup code Ard Biesheuvel
  2019-11-18 18:15 ` [PATCH v2 2/2] Revert "ARM: 8857/1: efi: enable CP15 DMB instructions before cleaning the cache" Ard Biesheuvel
  0 siblings, 2 replies; 3+ messages in thread
From: Ard Biesheuvel @ 2019-11-18 18:15 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: maz, rmk+kernel, linus.walleij, Ard Biesheuvel

From: Ard Biesheuvel <ard.biesheuvel@linaro.org>

While trying to test my v4.4 backport of the firmware/hypervisor based spectre
v1/v2 mitigations for 32-bit ARM, I noticed that KVM/qemu failed to boot my
kernel while it booted fine under TCG emulation.

As it turns out, KVM/qemu may instantiate the VCPU with support for CP15
barrier instructions disabled, causing them to UNDEF and crash the
decompressor.

I already fixed the same issue for UEFI boot, but since v4.4 does not support
that, I only noticed now that this is an issue for bare metal as well.

Changes since v1:
- instead of using v7 barriers in the v7 code, enable the CP15 barriers - this
  way, we can keep using the v7 routines for some v6 CPUs that implement CPUID
  instructions (causing them to take the v7 path) but not for the v7 barriers.
- applied Marc's and Linus's acks to #2 only

I have tested this via kernelci [0], which includes the v6 pogoplug that got
broken by the v1 version of this series.

[0] https://kernelci.org/build/ardb/branch/for-kernelci/kernel/v5.4-rc8-2-gcaea8d2861c8/

Cc: Russell King <rmk+kernel@armlinux.org.uk>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Marc Zyngier <maz@kernel.org>

Ard Biesheuvel (2):
  ARM/decompressor: enable CP15 barrier instructions in v7 cache setup
    code
  Revert "ARM: 8857/1: efi: enable CP15 DMB instructions before cleaning
    the cache"

 arch/arm/boot/compressed/head.S | 29 ++++++++++----------
 1 file changed, 14 insertions(+), 15 deletions(-)

-- 
2.20.1


_______________________________________________
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] 3+ messages in thread

* [PATCH v2 1/2] ARM/decompressor: enable CP15 barrier instructions in v7 cache setup code
  2019-11-18 18:15 [PATCH v2 0/2] ARM/decompressor: deal with disabled CP15 barrier instructions Ard Biesheuvel
@ 2019-11-18 18:15 ` Ard Biesheuvel
  2019-11-18 18:15 ` [PATCH v2 2/2] Revert "ARM: 8857/1: efi: enable CP15 DMB instructions before cleaning the cache" Ard Biesheuvel
  1 sibling, 0 replies; 3+ messages in thread
From: Ard Biesheuvel @ 2019-11-18 18:15 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: maz, rmk+kernel, linus.walleij, Ard Biesheuvel

Commit e17b1af96b2afc38e684aa2f1033387e2ed10029

  "ARM: 8857/1: efi: enable CP15 DMB instructions before cleaning the cache"

added some explicit handling of the CP15BEN bit in the SCTLR system
register, to ensure that CP15 barrier instructions are enabled, even
if we enter the decompressor via the EFI stub.

However, as it turns out, there are other ways in which we may end up
using CP15 barrier instructions without them being enabled. I.e., when
the decompressor startup code skips the cache_on() initially, we end
up calling cache_clean_flush() with the caches and MMU off, in which
case the CP15BEN bit in SCTLR may not be programmed either. And in
fact, cache_on() itself issues CP15 barrier instructions before actually
enabling them by programming the new SCTLR value (and issuing an ISB)

Since these routines are shared between v7 CPUs and older ones that
implement the CPUID extension as well, using the ordinary v7 barrier
instructions in this code is not possible, and so we should enable the
CP15 ones explicitly before issuing them. Note that a v7 ISB is still
required between programming the SCTLR register and using the CP15 barrier
instructions, and we should take care to branch over it if the CP15BEN
bit is already set, given that in that case, the CPU may not support it.

Cc: <stable@vger.kernel.org> # v4.4+
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm/boot/compressed/head.S | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 93dffed0ac6e..1af62baf7cd5 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -140,6 +140,17 @@
 #endif
 		.endm
 
+		.macro	enable_cp15_barriers, reg
+		mrc	p15, 0, \reg, c1, c0, 0	@ read SCTLR
+		tst	\reg, #(1 << 5)		@ CP15BEN bit set?
+		bne	.L_\@
+		orr	\reg, \reg, #(1 << 5)	@ CP15 barrier instructions
+		mcr	p15, 0, \reg, c1, c0, 0	@ write SCTLR
+ ARM(		.inst   0xf57ff06f		@ v7+ isb	)
+ THUMB(		isb						)
+.L_\@:
+		.endm
+
 		.section ".start", #alloc, #execinstr
 /*
  * sort out different calling conventions
@@ -820,6 +831,7 @@ __armv4_mmu_cache_on:
 		mov	pc, r12
 
 __armv7_mmu_cache_on:
+		enable_cp15_barriers	r11
 		mov	r12, lr
 #ifdef CONFIG_MMU
 		mrc	p15, 0, r11, c0, c1, 4	@ read ID_MMFR0
@@ -1209,6 +1221,7 @@ __armv6_mmu_cache_flush:
 		mov	pc, lr
 
 __armv7_mmu_cache_flush:
+		enable_cp15_barriers	r10
 		tst	r4, #1
 		bne	iflush
 		mrc	p15, 0, r10, c0, c1, 5	@ read ID_MMFR1
-- 
2.20.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] 3+ messages in thread

* [PATCH v2 2/2] Revert "ARM: 8857/1: efi: enable CP15 DMB instructions before cleaning the cache"
  2019-11-18 18:15 [PATCH v2 0/2] ARM/decompressor: deal with disabled CP15 barrier instructions Ard Biesheuvel
  2019-11-18 18:15 ` [PATCH v2 1/2] ARM/decompressor: enable CP15 barrier instructions in v7 cache setup code Ard Biesheuvel
@ 2019-11-18 18:15 ` Ard Biesheuvel
  1 sibling, 0 replies; 3+ messages in thread
From: Ard Biesheuvel @ 2019-11-18 18:15 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: maz, rmk+kernel, linus.walleij, Ard Biesheuvel

This reverts commit e17b1af96b2afc38e684aa2f1033387e2ed10029, which is
no longer necessary now that the v7 specific routines take care not to
issue CP15 barrier instructions before they are enabled in SCTLR.

Acked-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm/boot/compressed/head.S | 16 +---------------
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 1af62baf7cd5..9fe90c71f373 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -1460,21 +1460,7 @@ ENTRY(efi_stub_entry)
 
 		@ Preserve return value of efi_entry() in r4
 		mov	r4, r0
-
-		@ our cache maintenance code relies on CP15 barrier instructions
-		@ but since we arrived here with the MMU and caches configured
-		@ by UEFI, we must check that the CP15BEN bit is set in SCTLR.
-		@ Note that this bit is RAO/WI on v6 and earlier, so the ISB in
-		@ the enable path will be executed on v7+ only.
-		mrc	p15, 0, r1, c1, c0, 0	@ read SCTLR
-		tst	r1, #(1 << 5)		@ CP15BEN bit set?
-		bne	0f
-		orr	r1, r1, #(1 << 5)	@ CP15 barrier instructions
-		mcr	p15, 0, r1, c1, c0, 0	@ write SCTLR
- ARM(		.inst	0xf57ff06f		@ v7+ isb	)
- THUMB(		isb						)
-
-0:		bl	cache_clean_flush
+		bl	cache_clean_flush
 		bl	cache_off
 
 		@ Set parameters for booting zImage according to boot protocol
-- 
2.20.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] 3+ messages in thread

end of thread, other threads:[~2019-11-18 18:16 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-11-18 18:15 [PATCH v2 0/2] ARM/decompressor: deal with disabled CP15 barrier instructions Ard Biesheuvel
2019-11-18 18:15 ` [PATCH v2 1/2] ARM/decompressor: enable CP15 barrier instructions in v7 cache setup code Ard Biesheuvel
2019-11-18 18:15 ` [PATCH v2 2/2] Revert "ARM: 8857/1: efi: enable CP15 DMB instructions before cleaning the cache" Ard Biesheuvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).