|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen stable-4.13] xen/arm: Add Cortex-A73 erratum 858921 workaround
commit 96fbc00d1d73b1f3344644b7aa607ff0355c206a
Author: Penny Zheng <penny.zheng@xxxxxxx>
AuthorDate: Mon Nov 9 16:21:10 2020 +0800
Commit: Stefano Stabellini <sstabellini@xxxxxxxxxx>
CommitDate: Fri Mar 19 11:26:33 2021 -0700
xen/arm: Add Cortex-A73 erratum 858921 workaround
CNTVCT_EL0 or CNTPCT_EL0 counter read in Cortex-A73 (all versions)
might return a wrong value when the counter crosses a 32bit boundary.
Until now, there is no case for Xen itself to access CNTVCT_EL0,
and it also should be the Guest OS's responsibility to deal with
this part.
But for CNTPCT, there exists several cases in Xen involving reading
CNTPCT, so a possible workaround is that performing the read twice,
and to return one or the other depending on whether a transition has
taken place.
Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx>
Reviewed-by: Wei Chen <Wei.Chen@xxxxxxx>
Reviewed-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
Acked-by: Julien Grall <jgrall@xxxxxxxxxx>
Acked-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
(cherry picked from commit 5505f5f8e7e805365cfe70b6a4af6115940bb749)
---
docs/misc/arm/silicon-errata.txt | 1 +
xen/arch/arm/Kconfig | 18 ++++++++++++++++++
xen/arch/arm/cpuerrata.c | 8 ++++++++
xen/arch/arm/vtimer.c | 2 +-
xen/include/asm-arm/cpuerrata.h | 2 ++
xen/include/asm-arm/cpufeature.h | 3 ++-
xen/include/asm-arm/time.h | 22 +++++++++++++++++++++-
7 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/docs/misc/arm/silicon-errata.txt b/docs/misc/arm/silicon-errata.txt
index 1f18a9df58..552c4151d3 100644
--- a/docs/misc/arm/silicon-errata.txt
+++ b/docs/misc/arm/silicon-errata.txt
@@ -51,6 +51,7 @@ stable hypervisors.
| ARM | Cortex-A57 | #1319537 | N/A
|
| ARM | Cortex-A72 | #1319367 | N/A
|
| ARM | Cortex-A72 | #853709 | N/A
|
+| ARM | Cortex-A73 | #858921 | ARM_ERRATUM_858921
|
| ARM | Cortex-A76 | #1165522 | N/A
|
| ARM | Neoverse-N1 | #1165522 | N/A
| ARM | MMU-500 | #842869 | N/A
|
diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index a51aa7bfa8..bcd05c4f02 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -228,6 +228,24 @@ config ARM64_ERRATUM_834220
If unsure, say Y.
+config ARM_ERRATUM_858921
+ bool "Cortex-A73: 858921: Possible wrong read value for CNTVCT or
CNTPCT"
+ default y
+ help
+ This option adds an alternative code sequence to work around ARM
+ erratum 858921 on Cortex-A73 (all versions).
+
+ Affected Cortex-A73 might return wrong read value for CNTVCT or CNTPCT
+ when the counter crosses a 32bit boundary.
+
+ The workaround involves performing the read twice, and to return
+ one or the other value depending on whether a transition has taken
place.
+ Please note that this does not necessarily enable the workaround,
+ as it depends on the alternative framework, which will only patch
+ the kernel if an affected CPU is detected.
+
+ If unsure, say Y.
+
endmenu
config ARM64_HARDEN_BRANCH_PREDICTOR
diff --git a/xen/arch/arm/cpuerrata.c b/xen/arch/arm/cpuerrata.c
index 9f7169a6a6..12063c9001 100644
--- a/xen/arch/arm/cpuerrata.c
+++ b/xen/arch/arm/cpuerrata.c
@@ -474,6 +474,14 @@ static const struct arm_cpu_capabilities arm_errata[] = {
.capability = ARM_SSBD,
.matches = has_ssbd_mitigation,
},
+#endif
+#ifdef CONFIG_ARM_ERRATUM_858921
+ {
+ /* Cortex-A73 (all versions) */
+ .desc = "ARM erratum 858921",
+ .capability = ARM_WORKAROUND_858921,
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
+ },
#endif
{
/* Neoverse r0p0 - r2p0 */
diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
index a80009882f..43a0f1fde8 100644
--- a/xen/arch/arm/vtimer.c
+++ b/xen/arch/arm/vtimer.c
@@ -62,7 +62,7 @@ static void virt_timer_expired(void *data)
int domain_vtimer_init(struct domain *d, struct xen_arch_domainconfig *config)
{
- d->arch.virt_timer_base.offset = READ_SYSREG64(CNTPCT_EL0);
+ d->arch.virt_timer_base.offset = get_cycles();
d->time_offset_seconds = ticks_to_ns(d->arch.virt_timer_base.offset -
boot_count);
do_div(d->time_offset_seconds, 1000000000);
diff --git a/xen/include/asm-arm/cpuerrata.h b/xen/include/asm-arm/cpuerrata.h
index 88ef3ca934..8d7e7b9375 100644
--- a/xen/include/asm-arm/cpuerrata.h
+++ b/xen/include/asm-arm/cpuerrata.h
@@ -28,6 +28,8 @@ static inline bool check_workaround_##erratum(void)
\
CHECK_WORKAROUND_HELPER(766422, ARM32_WORKAROUND_766422, CONFIG_ARM_32)
CHECK_WORKAROUND_HELPER(834220, ARM64_WORKAROUND_834220, CONFIG_ARM_64)
CHECK_WORKAROUND_HELPER(ssbd, ARM_SSBD, CONFIG_ARM_SSBD)
+CHECK_WORKAROUND_HELPER(858921, ARM_WORKAROUND_858921,
+ CONFIG_ARM_ERRATUM_858921)
#undef CHECK_WORKAROUND_HELPER
diff --git a/xen/include/asm-arm/cpufeature.h b/xen/include/asm-arm/cpufeature.h
index 6bff5ce131..29753fee78 100644
--- a/xen/include/asm-arm/cpufeature.h
+++ b/xen/include/asm-arm/cpufeature.h
@@ -45,8 +45,9 @@
#define ARM_SSBD 7
#define ARM_SMCCC_1_1 8
#define ARM64_WORKAROUND_AT_SPECULATE 9
+#define ARM_WORKAROUND_858921 10
-#define ARM_NCAPS 10
+#define ARM_NCAPS 11
#ifndef __ASSEMBLY__
diff --git a/xen/include/asm-arm/time.h b/xen/include/asm-arm/time.h
index 9cb6f9b0b4..1b2c13614b 100644
--- a/xen/include/asm-arm/time.h
+++ b/xen/include/asm-arm/time.h
@@ -3,6 +3,7 @@
#include <asm/sysregs.h>
#include <asm/system.h>
+#include <asm/cpuerrata.h>
#define DT_MATCH_TIMER \
DT_MATCH_COMPATIBLE("arm,armv7-timer"), \
@@ -13,7 +14,26 @@ typedef uint64_t cycles_t;
static inline cycles_t get_cycles (void)
{
isb();
- return READ_SYSREG64(CNTPCT_EL0);
+ /*
+ * ARM_WORKAROUND_858921: Cortex-A73 (all versions) counter read
+ * can return a wrong value when the counter crosses a 32bit boundary.
+ */
+ if ( !check_workaround_858921() )
+ return READ_SYSREG64(CNTPCT_EL0);
+ else
+ {
+ /*
+ * A recommended workaround for erratum 858921 is to:
+ * 1- Read twice CNTPCT.
+ * 2- Compare bit[32] of the two read values.
+ * - If bit[32] is different, keep the old value.
+ * - If bit[32] is the same, keep the new value.
+ */
+ cycles_t old, new;
+ old = READ_SYSREG64(CNTPCT_EL0);
+ new = READ_SYSREG64(CNTPCT_EL0);
+ return (((old ^ new) >> 32) & 1) ? old : new;
+ }
}
/* List of timer's IRQ */
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |