From: David Laight <david.laight.linux@gmail.com>
To: Zong Li <zong.li@sifive.com>
Cc: Guo Ren <guoren@kernel.org>,
Vivian Wang <wangruikang@iscas.ac.cn>,
zhangzhanpeng.jasper@bytedance.com, alex@ghiti.fr,
aou@eecs.berkeley.edu, cuiyunhui@bytedance.com,
iommu@lists.linux.dev, joro@8bytes.org,
linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org,
luxu.kernel@bytedance.com, palmer@dabbelt.com, pjw@kernel.org,
robin.murphy@arm.com, tjeznach@rivosinc.com, will@kernel.org,
yuanzhu@bytedance.com
Subject: Re: [PATCH v1] iommu/riscv: Support 32-bit register accesses
Date: Fri, 28 Aug 2026 08:52:11 +0100 [thread overview]
Message-ID: <20260828085211.2c8e6b74@pumpkin> (raw)
In-Reply-To: <CANXhq0qtt7U3jKEB4drvSn7gg55nwWm8VFnfY-NRGjBaWVr_MQ@mail.gmail.com>
On Fri, 28 Aug 2026 10:52:08 +0800
Zong Li <zong.li@sifive.com> wrote:
> On Fri, Jun 19, 2026 at 12:02 AM David Laight
> <david.laight.linux@gmail.com> wrote:
> >
> > On Thu, 18 Jun 2026 17:51:34 +0800
> > Guo Ren <guoren@kernel.org> wrote:
> >
> > > Hi Vivian,
> > >
> > > As noted in the RISC-V IOMMU Specification, Chapter 6:
> > > > Whether an 8-byte access to an IOMMU register is single-copy atomic is UNSPECIFIED, and such an access may appear, internally to the IOMMU, as if two separate 4-byte accesses — first to the high half and second to the low half — were performed.
> > >
> > > Therefore, the atomicity of 64-bit MMIO accesses is UNSPECIFIED and
> > > not clearly defined in the current ratified RISC-V IOMMU
> > > specification. To handle this correctly, the Linux RISC-V IOMMU driver
> > > should fall back to 32-bit MMIO accesses when reading 64-bit registers
> > > (e.g., performance counters). The behavior of 32-bit MMIO accesses is
> > > more precisely defined in the RISC-V IOMMU specification.
> > >
> > > Thus, many hardware vendors implement 32-bit MMIO (rather than 64-bit
> > > MMIO) based on the current ratified RISC-V IOMMU specification, and
> > > this driver does not appear to benefit from 64-bit MMIO access either.
> > > Performance is fundamentally constrained by bus latency; assuming that
> > > simply reducing the number of accesses will improve performance is an
> > > oversimplification that ignores the underlying hardware
> > > characteristics.
> >
> > If the bus latency is significant it is almost certainly worth using
> > memory accesses to avoid re-reading the hi register.
> >
> > Something like this might work:
> >
> > static volatile u32 hi_prev, lo_prev;
> >
> > u32 hi = read_reg_hi();
> > u32 lo = read_reg_lo();
> >
> > if (lo <= lo_prev || hi != hi_prev) {
> > u32 hi_tmp = read_reg_hi;
> > if (hi_tmp != hi) {
> > hi = hi_tmp;
> > lo = 0;
> > }
> > lo_prev = ~0u;
> > hi_prev = hi;
> > }
> > lo_prev = lo;
> > return (u64)hi << 32 | lo;
> >
>
> Hi Daivd,
>
> I included this in my v5 of the IOMMU PMU series, but we noticed that
> sashiko-bot AI reported two issues:
I did say 'something like this' might work....
David
>
> 1: The lo_prev is immediately overwritten:
> The trailing 'pmu->lo_prev[idx] = lo;' is outside the if block and
> runs unconditionally, so the 'lo_prev = ~0u' is clobbered before the
> function even returns. It never survives to the next call. lo_prev
> ends up holding the guessed value (typically 0) instead, which is a
> perfectly ordinary small number, and the intended "always re-verify
> next time" behaviour never happens. The sentinel write was effectively
> dead code.
>
> 2: The wrap check itself can miss a wrap
> Here is a concrete sequence. Assume a previous call left hi_prev = 1
> and lo_prev = 5, i.e. the counter was 0x1_00000005. Some time later
> the counter has advanced close to 0x1_FFFFFFFF:
>
> 1. hi = readl(addr + 4) -> counter is 0x1_FFFFFFF0, so hi = 1
> 2. the counter crosses the boundary and becomes 0x2_00000008
> 3. lo = readl(addr) -> lo = 8
>
> The check then evaluates:
>
> lo (8) <= lo_prev (5) -> false
> hi (1) != hi_prev (1) -> false
>
> Both are false, so the fast path is taken and 0x1_00000008 is
> returned. The true value is 0x2_00000008, so the result is short by
> 2^32 and the third read of the high half never even executes.
>
> Both situations share the same root cause: It puts the reliable check
> (the third read) inside an if guarded by the unreliable cross-call
> heuristic 'lo <= lo_prev || hi != hi_prev)'
> Case 1 is an issue in the bookkeeping that heuristic depends on, and
> case 2 shows that even with correct bookkeeping the heuristic is not
> sound.
>
> To make everything simpler, I would use your first version for the
> latest IOMMU PMU series:
>
> hi = read_hi();
> lo = read_lo();
> if (hi != read_hi()) {
> // Pick a value that happened while doing the reads.
> hi++;
> lo = 0;
> }
>
> > It shouldn't need any locking but the accesses do need to be ordered.
> >
> > David
> >
> >
> >
> > _______________________________________________
> > linux-riscv mailing list
> > linux-riscv@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2026-08-28 7:52 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-15 6:48 Zhanpeng Zhang
2026-06-15 8:21 ` Andreas Schwab
2026-06-15 9:51 ` [External] " Zhanpeng Zhang
2026-06-15 9:59 ` David Laight
2026-06-15 13:21 ` [External] " Zhanpeng Zhang
2026-06-15 12:38 ` Guo Ren
2026-06-15 13:23 ` [External] " Zhanpeng Zhang
2026-06-16 10:36 ` David Laight
2026-06-16 15:47 ` Guo Ren
2026-06-16 19:51 ` David Laight
2026-06-17 16:24 ` Guo Ren
2026-06-17 21:54 ` David Laight
2026-06-18 3:36 ` Guo Ren
2026-06-18 3:20 ` Vivian Wang
2026-06-18 3:45 ` Guo Ren
2026-06-18 7:33 ` Vivian Wang
2026-06-18 9:51 ` Guo Ren
2026-06-18 10:01 ` Vivian Wang
2026-06-18 13:36 ` David Laight
2026-06-18 16:40 ` Guo Ren
2026-06-23 9:20 ` Zong Li
2026-06-28 8:20 ` Guo Ren
2026-06-29 1:15 ` Zong Li
2026-06-26 9:18 ` Zhanpeng Zhang
2026-08-28 2:52 ` Zong Li
2026-08-28 7:52 ` David Laight [this message]
2026-08-28 8:41 ` Zong Li
2026-07-13 6:09 ` [PATCH v2] iommu/riscv: Use 32-bit MMIO accesses for 64-bit registers Zhanpeng Zhang
2026-07-13 7:00 ` Guo Ren
2026-07-13 8:24 ` Zhanpeng Zhang
2026-07-13 12:29 ` [PATCH v3] " Zhanpeng Zhang
2026-07-14 2:02 ` Guo Ren
2026-07-14 7:10 ` Tomasz Jeznach
2026-07-14 12:27 ` Robin Murphy
2026-07-14 13:24 ` Guo Ren
2026-07-14 14:53 ` David Laight
2026-07-14 16:53 ` Guo Ren
2026-07-14 21:02 ` David Laight
2026-07-15 2:37 ` Guo Ren
2026-07-14 13:55 ` Guo Ren
2026-07-15 9:43 ` Chen Pei
2026-07-16 3:13 ` Zong Li
2026-07-16 4:04 ` Guo Ren
2026-07-16 6:59 ` Zong Li
2026-07-16 8:23 ` Guo Ren
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=20260828085211.2c8e6b74@pumpkin \
--to=david.laight.linux@gmail.com \
--cc=alex@ghiti.fr \
--cc=aou@eecs.berkeley.edu \
--cc=cuiyunhui@bytedance.com \
--cc=guoren@kernel.org \
--cc=iommu@lists.linux.dev \
--cc=joro@8bytes.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=luxu.kernel@bytedance.com \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=robin.murphy@arm.com \
--cc=tjeznach@rivosinc.com \
--cc=wangruikang@iscas.ac.cn \
--cc=will@kernel.org \
--cc=yuanzhu@bytedance.com \
--cc=zhangzhanpeng.jasper@bytedance.com \
--cc=zong.li@sifive.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
all inboxes | Powered by JetHome®