|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] xen/arm: Add Cortex-A73 erratum 858921 workaround
Hi,
> On 9 Nov 2020, at 08:21, Penny Zheng <Penny.Zheng@xxxxxxx> wrote:
>
> 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: Bertrand Marquis <bertrand.marquis@xxxxxxx>
Regards
Bertrand
> ---
> 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 2777388265..f938dd21bd 100644
> --- a/xen/arch/arm/Kconfig
> +++ b/xen/arch/arm/Kconfig
> @@ -226,6 +226,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 6731d873e8..567911d380 100644
> --- a/xen/arch/arm/cpuerrata.c
> +++ b/xen/arch/arm/cpuerrata.c
> @@ -469,6 +469,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 6d39fc944f..c2b27915c6 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 10878ead8a..016a9fe203 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 */
> --
> 2.25.1
>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |