From: Shanker Donthineni <sdonthineni@nvidia.com>
To: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>,
Vladimir Murzin <vladimir.murzin@arm.com>,
Jason Gunthorpe <jgg@nvidia.com>,
linux-arm-kernel@lists.infradead.org,
Mark Rutland <mark.rutland@arm.com>,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
Vikram Sethi <vsethi@nvidia.com>,
Jason Sequeira <jsequeira@nvidia.com>
Subject: Re: [PATCH v3] arm64: errata: Workaround NVIDIA Olympus device store/load ordering erratum
Date: Thu, 11 Jun 2026 09:08:09 -0500 [thread overview]
Message-ID: <aaad3692-74d5-4048-ac5c-ca47ef65c32d@nvidia.com> (raw)
In-Reply-To: <aiq5VigmtZq9GlAm@willie-the-truck>
Hi Will,
On 6/11/2026 8:34 AM, Will Deacon wrote:
> External email: Use caution opening links or attachments
>
>
> On Wed, Jun 10, 2026 at 11:48:22AM -0500, Shanker Donthineni wrote:
>> On systems with NVIDIA Olympus cores, a Device-nGnR* load can be
>> observed by a peripheral before an older, non-overlapping Device-nGnR*
>> store to the same peripheral. This breaks the program-order guarantee
>> that software expects for Device-nGnR* accesses and can leave a
>> peripheral in an incorrect state, as a load is observed before an
>> earlier store takes effect.
>>
>> The erratum can occur only when all of the following apply:
>>
>> - A PE executes a Device-nGnR* store followed by a younger
>> Device-nGnR* load.
>> - The store is not a store-release.
>> - The accesses target the same peripheral and do not overlap in bytes.
>> - There is at most one intervening Device-nGnR* store in program
>> order, and there are no intervening Device-nGnR* loads.
>> - There is no DSB, and no DMB that orders loads, between the store and
>> the load.
>> - Specific micro-architectural and timing conditions occur.
>>
>> Promote the raw MMIO store helpers (__raw_writeb/w/l/q) from plain str*
>> to stlr* (Store-Release), which removes the "store is not a
>> store-release" condition for every device write the kernel issues.
>> Because writel() and writel_relaxed() are both built on __raw_writel()
>> in asm-generic/io.h, patching the raw variants covers both the
>> non-relaxed and relaxed APIs without touching the higher layers. Note
>> that writel()'s own barrier sits before the store, so it does not order
>> the store against a subsequent readl(); the store-release promotion is
>> what provides that ordering.
>>
>> Like ARM64_ERRATUM_832075 on the load side, the change is gated on a new
>> ARM64_WORKAROUND_DEVICE_STORE_RELEASE capability and only activated on
>> parts that match MIDR_NVIDIA_OLYMPUS, so unaffected CPUs continue to use
>> the plain str* sequence.
>>
>> Note: stlr* only supports base-register addressing, so affected CPUs use
>> a base-register stlr* path. Unaffected CPUs keep the original
>> offset-addressed str* sequence introduced by commit d044d6ba6f02
>> ("arm64: io: permit offset addressing").
>>
>> The __const_memcpy_toio_aligned32() and __const_memcpy_toio_aligned64()
>> helpers are left unchanged. These helpers are intended for
>> write-combining mappings, which are Normal-NC on arm64. Replacing their
>> contiguous str* groups would defeat the write-combining behavior used to
>> improve store performance.
>>
>> Co-developed-by: Vikram Sethi <vsethi@nvidia.com>
>> Signed-off-by: Vikram Sethi <vsethi@nvidia.com>
>> Signed-off-by: Shanker Donthineni <sdonthineni@nvidia.com>
>> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>> ---
>> Changes since v2:
>> - Reworked the raw MMIO write helpers so unaffected CPUs keep the
>> existing offset-addressed STR sequence, while affected CPUs use the
>> base-register STLR path.
>> - Updated the commit message to match the code changes.
>> - Rebased on top of the arm64 for-next/errata branch:
>> https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=for-next/errata
>>
>> Changes since v1:
>> - Updated the commit message based on feedback from Vladimir Murzin.
>>
>> Documentation/arch/arm64/silicon-errata.rst | 2 ++
>> arch/arm64/Kconfig | 23 ++++++++++++++++
>> arch/arm64/include/asm/io.h | 30 +++++++++++++++++++++
>> arch/arm64/kernel/cpu_errata.c | 8 ++++++
>> arch/arm64/tools/cpucaps | 1 +
>> 5 files changed, 64 insertions(+)
>>
>> diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
>> index ad09bbb10da80..fc45125dc2f80 100644
>> --- a/Documentation/arch/arm64/silicon-errata.rst
>> +++ b/Documentation/arch/arm64/silicon-errata.rst
>> @@ -298,6 +298,8 @@ stable kernels.
>> +----------------+-----------------+-----------------+-----------------------------+
>> | NVIDIA | Carmel Core | N/A | NVIDIA_CARMEL_CNP_ERRATUM |
>> +----------------+-----------------+-----------------+-----------------------------+
>> +| NVIDIA | Olympus core | T410-OLY-1027 | NVIDIA_OLYMPUS_1027_ERRATUM |
>> ++----------------+-----------------+-----------------+-----------------------------+
>> | NVIDIA | Olympus core | T410-OLY-1029 | ARM64_ERRATUM_4118414 |
>> +----------------+-----------------+-----------------+-----------------------------+
>> | NVIDIA | T241 GICv3/4.x | T241-FABRIC-4 | N/A |
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index c65cef81be86a..d633eb70de1ac 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -564,6 +564,29 @@ config ARM64_ERRATUM_832075
>>
>> If unsure, say Y.
>>
>> +config NVIDIA_OLYMPUS_1027_ERRATUM
>> + bool "NVIDIA Olympus: device store/load ordering erratum"
>> + default y
>> + help
>> + This option adds an alternative code sequence to work around an
>> + NVIDIA Olympus core erratum where a Device-nGnR* store can be
>> + observed by a peripheral after a younger Device-nGnR* load to the
>> + same peripheral. This breaks the program order that drivers rely
>> + on for MMIO and can leave a device in an incorrect state.
>> +
>> + The workaround promotes the raw MMIO store helpers
>> + (__raw_writeb/w/l/q) to Store-Release (STLR), which restores the
>> + required ordering. Because writel() and writel_relaxed() are built
>> + on __raw_writel(), both are covered without changes to the higher
>> + layers.
>> +
>> + The fix is applied through the alternatives framework, so enabling
>> + this option does not by itself activate the workaround: it is
>> + patched in only when an affected CPU is detected, and is a no-op on
>> + unaffected CPUs.
>> +
>> + If unsure, say Y.
>> +
>> config ARM64_ERRATUM_834220
>> bool "Cortex-A57: 834220: Stage 2 translation fault might be incorrectly reported in presence of a Stage 1 fault (rare)"
>> depends on KVM
>> diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
>> index 8cbd1e96fd50b..801223e754c90 100644
>> --- a/arch/arm64/include/asm/io.h
>> +++ b/arch/arm64/include/asm/io.h
>> @@ -22,10 +22,22 @@
>> /*
>> * Generic IO read/write. These perform native-endian accesses.
>> */
>> +static __always_inline bool arm64_needs_device_store_release(void)
>> +{
>> + return alternative_has_cap_unlikely(
>> + ARM64_WORKAROUND_DEVICE_STORE_RELEASE);
>> +}
>> +
>> #define __raw_writeb __raw_writeb
>> static __always_inline void __raw_writeb(u8 val, volatile void __iomem *addr)
>> {
>> volatile u8 __iomem *ptr = addr;
>> +
>> + if (arm64_needs_device_store_release()) {
>> + asm volatile("stlrb %w0, [%1]" : : "rZ" (val), "r" (addr));
>> + return;
>> + }
>> +
>> asm volatile("strb %w0, %1" : : "rZ" (val), "Qo" (*ptr));
>> }
> Use an 'else' clause instead of the early return? (similarly for the other
> changes).
I agree. I’ll rework the raw write helpers to use an explicit if/else
form instead of returning early from the STLR path.
>
> I still reckon you should do something with the memcpy-to-io routines.
> A simple option could be to make dgh() a dmb on parts with the erratum?
> That at least moves the barrier out of the loop.
For the memcpy-to-IO routines, would it be acceptable to address the erratum by
patching dgh() to a DMB OSH on affected CPUs, as shown below? I’ll also sync
with the Olympus CPU hardware team to confirm this approach for the v4 patch.
#define dgh() asm volatile(ALTERNATIVE("hint #6", "dmb osh", \
ARM64_WORKAROUND_DEVICE_STORE_RELEASE) \
: : : "memory")
This keeps the existing memcpy-to-IO store sequences unchanged while placing the
ordering barrier outside the copy loop as you suggested.
-Shanker
next prev parent reply other threads:[~2026-06-11 14:08 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-10 16:48 [PATCH v3] arm64: errata: Workaround NVIDIA Olympus device store/load ordering erratum Shanker Donthineni
2026-06-11 13:34 ` Will Deacon
2026-06-11 14:08 ` Shanker Donthineni [this message]
2026-06-11 15:08 ` Vladimir Murzin
2026-06-11 16:00 ` Shanker Donthineni
2026-06-11 17:49 ` Jason Gunthorpe
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=aaad3692-74d5-4048-ac5c-ca47ef65c32d@nvidia.com \
--to=sdonthineni@nvidia.com \
--cc=catalin.marinas@arm.com \
--cc=jgg@nvidia.com \
--cc=jsequeira@nvidia.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=vladimir.murzin@arm.com \
--cc=vsethi@nvidia.com \
--cc=will@kernel.org \
/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