Linux KVM/arm64 development list
 help / color / mirror / Atom feed
From: D Scott Phillips <scott@os.amperecomputing.com>
To: Marc Zyngier <maz@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>,
	James Clark <james.clark@linaro.org>,
	James Morse <james.morse@arm.com>,
	Joey Gouly <joey.gouly@arm.com>,
	Kevin Brodsky <kevin.brodsky@arm.com>,
	Mark Brown <broonie@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Oliver Upton <oliver.upton@linux.dev>,
	"Rob Herring  (Arm)" <robh@kernel.org>,
	Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>,
	Shiqi Liu <shiqiliu@hust.edu.cn>, Will Deacon <will@kernel.org>,
	Yicong Yang <yangyicong@hisilicon.com>,
	kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2] arm64: errata: Work around AmpereOne's erratum AC04_CPU_23
Date: Thu, 01 May 2025 08:17:53 -0700	[thread overview]
Message-ID: <86a57w9x7i.fsf@scott-ph-mail.amperecomputing.com> (raw)
In-Reply-To: <865xilir33.wl-maz@kernel.org>

Marc Zyngier <maz@kernel.org> writes:

> On Fri, 25 Apr 2025 03:47:41 +0100,
> D Scott Phillips <scott@os.amperecomputing.com> wrote:
>> 
>> Updates to HCR_EL2 can rarely corrupt simultaneous translations for data
>> addresses initiated by load/store instructions. Only instruction
>> initiated translations are vulnerable, not translations from prefetches
>> for example. A DSB before the store to HCR_EL2 is sufficient to prevent older
>> instructions from hitting the window for corruption, and an ISB after
>> is sufficient to prevent younger instructions from hitting the window
>> for corruption.
>> 
>> Signed-off-by: D Scott Phillips <scott@os.amperecomputing.com>
>> ---
>> v1: https://lore.kernel.org/kvmarm/20250415154711.1698544-2-scott@os.amperecomputing.com/
>> Changes since v1:
>>  - Add a write_sysreg_hcr() helper (Oliver)
>>  - Add more specific wording in the errata description (Oliver & Marc)
>> 
>>  arch/arm64/Kconfig                      | 17 +++++++++++++++++
>>  arch/arm64/include/asm/hardirq.h        |  4 ++--
>>  arch/arm64/include/asm/sysreg.h         | 10 ++++++++++
>>  arch/arm64/kernel/cpu_errata.c          | 14 ++++++++++++++
>>  arch/arm64/kvm/at.c                     |  8 ++++----
>>  arch/arm64/kvm/hyp/include/hyp/switch.h |  2 +-
>>  arch/arm64/kvm/hyp/nvhe/mem_protect.c   |  2 +-
>>  arch/arm64/kvm/hyp/nvhe/switch.c        |  2 +-
>>  arch/arm64/kvm/hyp/vhe/switch.c         |  2 +-
>>  arch/arm64/kvm/hyp/vhe/tlb.c            |  4 ++--
>>  arch/arm64/tools/cpucaps                |  1 +
>>  11 files changed, 54 insertions(+), 12 deletions(-)
>> 
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index a182295e6f08b..3ae4e80e3002b 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -464,6 +464,23 @@ config AMPERE_ERRATUM_AC03_CPU_38
>>  
>>  	  If unsure, say Y.
>>  
>> +config AMPERE_ERRATUM_AC04_CPU_23
>> +        bool "AmpereOne: AC04_CPU_23:  Failure to synchronize writes to HCR_EL2 may corrupt address translations."
>> +	default y
>> +	help
>> +	  This option adds an alternative code sequence to work around Ampere
>> +	  errata AC04_CPU_23 on AmpereOne.
>> +
>> +	  Updates to HCR_EL2 can rarely corrupt simultaneous translations for
>> +	  data addresses initiated by load/store instructions. Only
>> +	  instruction initiated translations are vulnerable, not translations
>> +	  from prefetches for example. A DSB before the store to HCR_EL2 is
>> +	  sufficient to prevent older instructions from hitting the window
>> +	  for corruption, and an ISB after is sufficient to prevent younger
>> +	  instructions from hitting the window for corruption.
>> +
>> +	  If unsure, say Y.
>> +
>>  config ARM64_WORKAROUND_CLEAN_CACHE
>>  	bool
>>  
>> diff --git a/arch/arm64/include/asm/hardirq.h b/arch/arm64/include/asm/hardirq.h
>> index cbfa7b6f2e098..77d6b8c63d4e6 100644
>> --- a/arch/arm64/include/asm/hardirq.h
>> +++ b/arch/arm64/include/asm/hardirq.h
>> @@ -41,7 +41,7 @@ do {									\
>>  									\
>>  	___hcr = read_sysreg(hcr_el2);					\
>>  	if (!(___hcr & HCR_TGE)) {					\
>> -		write_sysreg(___hcr | HCR_TGE, hcr_el2);		\
>> +		write_sysreg_hcr(___hcr | HCR_TGE);			\
>>  		isb();							\
>>  	}								\
>>  	/*								\
>> @@ -82,7 +82,7 @@ do {									\
>>  	 */								\
>>  	barrier();							\
>>  	if (!___ctx->cnt && !(___hcr & HCR_TGE))			\
>> -		write_sysreg(___hcr, hcr_el2);				\
>> +		write_sysreg_hcr(___hcr);				\
>>  } while (0)
>>  
>>  static inline void ack_bad_irq(unsigned int irq)
>> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
>> index 2639d3633073d..d41eeba7f8201 100644
>> --- a/arch/arm64/include/asm/sysreg.h
>> +++ b/arch/arm64/include/asm/sysreg.h
>> @@ -1185,6 +1185,16 @@
>>  		write_sysreg_s(__scs_new, sysreg);			\
>>  } while (0)
>>  
>> +#define write_sysreg_hcr(__val) do {					\
>> +	if(IS_ENABLED(CONFIG_AMPERE_ERRATUM_AC04_CPU_23) &&		\
>> +	   alternative_has_cap_unlikely(ARM64_WORKAROUND_AMPERE_AC04_CPU_23)) \
>> +		asm volatile("dsb nsh; msr hcr_el2, %x0; isb"		\
>> +			     : : "rZ" (__val));				\
>> +	else								\
>> +		asm volatile("msr hcr_el2, %x0"				\
>> +			     : : "rZ" (__val));				\
>> +} while (0)
>> +
>
> I'm worried that some of these accesses may occur before we compute
> the capabilities. I'd be more confident if the default was to have the
> workaround, and only to relax it once we know we're not on a broken
> system.

OK, will do

> But that leaves the question of the early stuff that runs before we
> get to C code. Are you sure this isn't affected by this issue (for
> example, the code in head.S, hyp-stub.S, and el2-setup.h)?

Ya, that's a good point. The corrupted translations can happen
speculatively, so there's every reason to think all those places also
need to be considered. I'll take a look everywhere now, not just at C.

>>  #define read_sysreg_par() ({						\
>>  	u64 par;							\
>>  	asm(ALTERNATIVE("nop", "dmb sy", ARM64_WORKAROUND_1508412));	\
>> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
>> index b55f5f7057502..60f1b70fc0845 100644
>> --- a/arch/arm64/kernel/cpu_errata.c
>> +++ b/arch/arm64/kernel/cpu_errata.c
>> @@ -557,6 +557,13 @@ static const struct midr_range erratum_ac03_cpu_38_list[] = {
>>  };
>>  #endif
>>  
>> +#ifdef CONFIG_AMPERE_ERRATUM_AC04_CPU_23
>> +static const struct midr_range erratum_ac04_cpu_23_list[] = {
>> +	MIDR_ALL_VERSIONS(MIDR_AMPERE1A),
>> +	{},
>> +};
>> +#endif
>> +
>>  const struct arm64_cpu_capabilities arm64_errata[] = {
>>  #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
>>  	{
>> @@ -875,6 +882,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>>  		.capability = ARM64_WORKAROUND_AMPERE_AC03_CPU_38,
>>  		ERRATA_MIDR_RANGE_LIST(erratum_ac03_cpu_38_list),
>>  	},
>> +#endif
>> +#ifdef CONFIG_AMPERE_ERRATUM_AC04_CPU_23
>> +	{
>> +		.desc = "AmpereOne erratum AC04_CPU_23",
>> +		.capability = ARM64_WORKAROUND_AMPERE_AC04_CPU_23,
>> +		ERRATA_MIDR_RANGE_LIST(erratum_ac04_cpu_23_list),
>> +	},
>>  #endif
>
> This needs to be captured in Documentation/arch/arm64/silicon-errata.rst.

OK, will do, thanks Marc.

      reply	other threads:[~2025-05-01 15:18 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-25  2:47 [PATCH v2] arm64: errata: Work around AmpereOne's erratum AC04_CPU_23 D Scott Phillips
2025-04-30 15:53 ` Marc Zyngier
2025-05-01 15:17   ` D Scott Phillips [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=86a57w9x7i.fsf@scott-ph-mail.amperecomputing.com \
    --to=scott@os.amperecomputing.com \
    --cc=broonie@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=james.clark@linaro.org \
    --cc=james.morse@arm.com \
    --cc=joey.gouly@arm.com \
    --cc=kevin.brodsky@arm.com \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=oliver.upton@linux.dev \
    --cc=robh@kernel.org \
    --cc=shameerali.kolothum.thodi@huawei.com \
    --cc=shiqiliu@hust.edu.cn \
    --cc=will@kernel.org \
    --cc=yangyicong@hisilicon.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox