|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen stable-4.17] xen/arm: Add Cortex-A77 erratum 1508412 handling
commit 3d0aa6f23d54a4d3c608010c58c1147a1500d865
Author: Luca Fancellu <luca.fancellu@xxxxxxx>
AuthorDate: Mon Jul 17 13:25:46 2023 +0100
Commit: Stefano Stabellini <stefano.stabellini@xxxxxxx>
CommitDate: Tue Aug 1 16:05:31 2023 -0700
xen/arm: Add Cortex-A77 erratum 1508412 handling
Cortex-A77 cores (r0p0, r1p0) could deadlock on a sequence of a
store-exclusive or read of PAR_EL1 and a load with device or non-cacheable
memory attributes.
A workaround is available, but it depends on a firmware counterpart.
The proposed workaround from the errata document is to modify the software
running at EL1 and above to include a DMB SY before and after accessing
PAR_EL1.
In conjunction to the above, the firmware needs to use a specific write
sequence to several IMPLEMENTATION DEFINED registers to have the hardware
insert a DMB SY after all load-exclusive and store-exclusive instructions.
Apply the workaround to Xen where PAR_EL1 is read, implementing an helper
function to do that.
Since Xen can be interrupted by irqs in any moment, add a barrier on
entry/exit when we are running on the affected cores.
A guest without the workaround can deadlock the system, so warn the users
of Xen with the above type of cores to use only trusted guests, by
printing a message on Xen startup.
This is XSA-436 / CVE-2023-34320.
Signed-off-by: Luca Fancellu <luca.fancellu@xxxxxxx>
[stefano: add XSA-436 to commit message]
Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxx>
Reviewed-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
Reviewed-by: Julien Grall <jgrall@xxxxxxxxxx>
---
SUPPORT.md | 2 ++
docs/misc/arm/silicon-errata.txt | 1 +
xen/arch/arm/Kconfig | 21 +++++++++++++++++++++
xen/arch/arm/arm64/entry.S | 19 +++++++++++++++++++
xen/arch/arm/cpuerrata.c | 16 ++++++++++++----
xen/arch/arm/domain.c | 2 +-
xen/arch/arm/include/asm/arm64/page.h | 12 ++++++------
xen/arch/arm/include/asm/cpufeature.h | 3 ++-
xen/arch/arm/include/asm/sysregs.h | 24 ++++++++++++++++++++++++
9 files changed, 88 insertions(+), 12 deletions(-)
diff --git a/SUPPORT.md b/SUPPORT.md
index cb504eec1e..c94c9cfe8f 100644
--- a/SUPPORT.md
+++ b/SUPPORT.md
@@ -39,8 +39,10 @@ supported in this document.
Status: Supported
Status, Cortex A57 r0p0-r1p1: Supported, not security supported
+ Status, Cortex A77 r0p0-r1p0: Supported, not security supported
For the Cortex A57 r0p0 - r1p1, see Errata 832075.
+For the Cortex A77 r0p0 - r1p0, see Errata 1508412.
## Host hardware support
diff --git a/docs/misc/arm/silicon-errata.txt b/docs/misc/arm/silicon-errata.txt
index 1925d8fd4e..c4e82df535 100644
--- a/docs/misc/arm/silicon-errata.txt
+++ b/docs/misc/arm/silicon-errata.txt
@@ -58,4 +58,5 @@ stable hypervisors.
| ARM | Cortex-A76 | #1286807 | ARM64_ERRATUM_1286807
|
| ARM | Neoverse-N1 | #1165522 | N/A
| ARM | Neoverse-N1 | #1286807 | ARM64_ERRATUM_1286807
|
+| ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412
|
| ARM | MMU-500 | #842869 | N/A
|
diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index 52a05f704d..87d541c411 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -318,6 +318,27 @@ config ARM64_ERRATUM_1286807
If unsure, say Y.
+config ARM64_ERRATUM_1508412
+ bool "Cortex-A77: 1508412: possible deadlock on sequence of NC/Device
load and store exclusive or PAR read"
+ default y
+ depends on ARM_64
+ help
+ This option adds a workaround for Arm Cortex-A77 erratum 1508412.
+
+ Affected Cortex-A77 cores (r0p0, r1p0) could deadlock on a sequence
+ of a store-exclusive or read of PAR_EL1 and a load with device or
+ non-cacheable memory attributes. The workaround depends on a firmware
+ counterpart.
+
+ Xen guests must also have the workaround implemented or they can
+ deadlock the system.
+
+ Work around the issue by inserting DMB SY barriers around PAR_EL1
+ register reads and warning Xen users. The DMB barrier is sufficient
+ to prevent a speculative PAR_EL1 read.
+
+ If unsure, say Y.
+
endmenu
config ARM64_HARDEN_BRANCH_PREDICTOR
diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
index 95f1a92684..95ff4e3e05 100644
--- a/xen/arch/arm/arm64/entry.S
+++ b/xen/arch/arm/arm64/entry.S
@@ -134,6 +134,16 @@
* position on the stack before.
*/
.macro entry, hyp, compat, save_x0_x1=1
+
+ /*
+ * Ensure any PAR_EL1 reads complete, in case we were interrupted
+ * between the PAR_EL1 read and the memory barrier for the erratum
+ * 1508412 workaround.
+ */
+ alternative_if ARM64_WORKAROUND_1508412
+ dmb sy
+ alternative_else_nop_endif
+
sub sp, sp, #(UREGS_SPSR_el1 - UREGS_LR) /* CPSR, PC, SP, LR */
.if \hyp == 0 /* Guest mode */
@@ -492,6 +502,15 @@ return_from_trap:
ldr lr, [sp], #(UREGS_SPSR_el1 - UREGS_LR) /* CPSR, PC, SP, LR */
+ /*
+ * Ensure any device/NC reads complete, in case we were interrupted
+ * between the memory barrier for the erratum 1508412 workaround and
+ * any PAR_EL1 read.
+ */
+ alternative_if ARM64_WORKAROUND_1508412
+ dmb sy
+ alternative_else_nop_endif
+
eret
sb
diff --git a/xen/arch/arm/cpuerrata.c b/xen/arch/arm/cpuerrata.c
index ae649d16ef..ea680fac2e 100644
--- a/xen/arch/arm/cpuerrata.c
+++ b/xen/arch/arm/cpuerrata.c
@@ -668,6 +668,14 @@ static const struct arm_cpu_capabilities arm_errata[] = {
.capability = ARM64_WORKAROUND_AT_SPECULATE,
MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
},
+#ifdef CONFIG_ARM64_ERRATUM_1508412
+ {
+ /* Cortex-A77 r0p0 - r1p0 */
+ .desc = "ARM erratum 1508412 (hypervisor portion)",
+ .capability = ARM64_WORKAROUND_1508412,
+ MIDR_RANGE(MIDR_CORTEX_A77, 0, 1),
+ },
+#endif
{
/* Cortex-A55 (All versions as erratum is open in SDEN v14) */
.desc = "ARM erratum 1530923",
@@ -686,11 +694,11 @@ void __init enable_errata_workarounds(void)
{
enable_cpu_capabilities(arm_errata);
-#ifdef CONFIG_ARM64_ERRATUM_832075
- if ( cpus_have_cap(ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE) )
+#if defined(CONFIG_ARM64_ERRATUM_832075) ||
defined(CONFIG_ARM64_ERRATUM_1508412)
+ if ( cpus_have_cap(ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE) ||
+ cpus_have_cap(ARM64_WORKAROUND_1508412) )
{
- printk_once("**** This CPU is affected by the errata 832075.
****\n"
- "**** Guests without CPU erratum workarounds can deadlock
the system! ****\n"
+ printk_once("**** Guests without CPU erratum workarounds can deadlock
the system! ****\n"
"**** Only trusted guests should be used.
****\n");
/* Taint the machine has being insecure */
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 38e22f12af..b9dce97d66 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -137,7 +137,7 @@ static void ctxt_switch_from(struct vcpu *p)
p->arch.ttbr1 = READ_SYSREG64(TTBR1_EL1);
if ( is_32bit_domain(p->domain) )
p->arch.dacr = READ_SYSREG(DACR32_EL2);
- p->arch.par = READ_SYSREG64(PAR_EL1);
+ p->arch.par = read_sysreg_par();
#if defined(CONFIG_ARM_32)
p->arch.mair0 = READ_CP32(MAIR0);
p->arch.mair1 = READ_CP32(MAIR1);
diff --git a/xen/arch/arm/include/asm/arm64/page.h
b/xen/arch/arm/include/asm/arm64/page.h
index 0cba266373..fbfe67bf89 100644
--- a/xen/arch/arm/include/asm/arm64/page.h
+++ b/xen/arch/arm/include/asm/arm64/page.h
@@ -48,11 +48,11 @@ static inline void invalidate_icache_local(void)
/* Ask the MMU to translate a VA for us */
static inline uint64_t __va_to_par(vaddr_t va)
{
- uint64_t par, tmp = READ_SYSREG64(PAR_EL1);
+ uint64_t par, tmp = read_sysreg_par();
asm volatile ("at s1e2r, %0;" : : "r" (va));
isb();
- par = READ_SYSREG64(PAR_EL1);
+ par = read_sysreg_par();
WRITE_SYSREG64(tmp, PAR_EL1);
return par;
}
@@ -60,28 +60,28 @@ static inline uint64_t __va_to_par(vaddr_t va)
/* Ask the MMU to translate a Guest VA for us */
static inline uint64_t gva_to_ma_par(vaddr_t va, unsigned int flags)
{
- uint64_t par, tmp = READ_SYSREG64(PAR_EL1);
+ uint64_t par, tmp = read_sysreg_par();
if ( (flags & GV2M_WRITE) == GV2M_WRITE )
asm volatile ("at s12e1w, %0;" : : "r" (va));
else
asm volatile ("at s12e1r, %0;" : : "r" (va));
isb();
- par = READ_SYSREG64(PAR_EL1);
+ par = read_sysreg_par();
WRITE_SYSREG64(tmp, PAR_EL1);
return par;
}
static inline uint64_t gva_to_ipa_par(vaddr_t va, unsigned int flags)
{
- uint64_t par, tmp = READ_SYSREG64(PAR_EL1);
+ uint64_t par, tmp = read_sysreg_par();
if ( (flags & GV2M_WRITE) == GV2M_WRITE )
asm volatile ("at s1e1w, %0;" : : "r" (va));
else
asm volatile ("at s1e1r, %0;" : : "r" (va));
isb();
- par = READ_SYSREG64(PAR_EL1);
+ par = read_sysreg_par();
WRITE_SYSREG64(tmp, PAR_EL1);
return par;
}
diff --git a/xen/arch/arm/include/asm/cpufeature.h
b/xen/arch/arm/include/asm/cpufeature.h
index c86a2e7f29..3a39fe4b5a 100644
--- a/xen/arch/arm/include/asm/cpufeature.h
+++ b/xen/arch/arm/include/asm/cpufeature.h
@@ -68,8 +68,9 @@
#define ARM_WORKAROUND_BHB_LOOP_32 14
#define ARM_WORKAROUND_BHB_SMCC_3 15
#define ARM_HAS_SB 16
+#define ARM64_WORKAROUND_1508412 17
-#define ARM_NCAPS 17
+#define ARM_NCAPS 18
#ifndef __ASSEMBLY__
diff --git a/xen/arch/arm/include/asm/sysregs.h
b/xen/arch/arm/include/asm/sysregs.h
index 5c5c51bbcd..61e30c9e51 100644
--- a/xen/arch/arm/include/asm/sysregs.h
+++ b/xen/arch/arm/include/asm/sysregs.h
@@ -9,6 +9,30 @@
# error "unknown ARM variant"
#endif
+#ifndef __ASSEMBLY__
+
+#include <asm/alternative.h>
+
+static inline register_t read_sysreg_par(void)
+{
+ register_t par_el1;
+
+ /*
+ * On Cortex-A77 r0p0 and r1p0, read access to PAR_EL1 shall include a
+ * DMB SY before and after accessing it, as part of the workaround for the
+ * errata 1508412.
+ */
+ asm volatile(ALTERNATIVE("nop", "dmb sy", ARM64_WORKAROUND_1508412,
+ CONFIG_ARM64_ERRATUM_1508412));
+ par_el1 = READ_SYSREG64(PAR_EL1);
+ asm volatile(ALTERNATIVE("nop", "dmb sy", ARM64_WORKAROUND_1508412,
+ CONFIG_ARM64_ERRATUM_1508412));
+
+ return par_el1;
+}
+
+#endif /* !__ASSEMBLY__ */
+
#endif /* __ASM_ARM_SYSREGS_H */
/*
* Local variables:
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.17
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |