From: Alice Ryhl <aliceryhl@google.com>
To: Zhi Wang <zhiw@nvidia.com>
Cc: rust-for-linux@vger.kernel.org, dakr@kernel.org,
bhelgaas@google.com, kwilczynski@kernel.org, ojeda@kernel.org,
alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net,
bjorn3_gh@protonmail.com, lossin@kernel.org,
a.hindborg@kernel.org, tmgross@umich.edu,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
cjia@nvidia.com, smitra@nvidia.com, ankita@nvidia.com,
aniketa@nvidia.com, kwankhede@nvidia.com, targupta@nvidia.com,
zhiwang@kernel.org, acourbot@nvidia.com, joelagnelf@nvidia.com,
jhubbard@nvidia.com, markus.probst@posteo.de,
Bjorn Helgaas <helgaas@kernel.org>
Subject: Re: [PATCH v3 1/5] rust: io: factor common I/O helpers into Io trait
Date: Fri, 31 Oct 2025 09:07:04 +0000 [thread overview]
Message-ID: <aQR8OPVnU_fPJTCI@google.com> (raw)
In-Reply-To: <20251030154842.450518-2-zhiw@nvidia.com>
On Thu, Oct 30, 2025 at 03:48:38PM +0000, Zhi Wang wrote:
> The previous Io<SIZE> type combined both the generic I/O access helpers
> and MMIO implementation details in a single struct.
>
> To establish a cleaner layering between the I/O interface and its concrete
> backends, paving the way for supporting additional I/O mechanisms in the
> future, Io<SIZE> need to be factored.
>
> Factor the common helpers into a new Io trait, and move the MMIO-specific
> logic into a dedicated Mmio<SIZE> type implementing that trait. Rename the
> IoRaw to MmioRaw and update the bus MMIO implementations to use MmioRaw.
>
> No functional change intended.
>
> Cc: Alexandre Courbot <acourbot@nvidia.com>
> Cc: Bjorn Helgaas <helgaas@kernel.org>
> Cc: Danilo Krummrich <dakr@kernel.org>
> Cc: John Hubbard <jhubbard@nvidia.com>
> Signed-off-by: Zhi Wang <zhiw@nvidia.com>
> +/// Represents a region of I/O space of a fixed size.
> +///
> +/// Provides common helpers for offset validation and address
> +/// calculation on top of a base address and maximum size.
> +///
> +/// Types implementing this trait (e.g. MMIO BARs or PCI config
> +/// regions) can share the same accessors.
> +pub trait Io<const SIZE: usize> {
I would consider moving SIZE to an associated constant.
pub trait Io {
const MIN_SIZE: usize;
...
}
If it's a generic parameter, then the same type can implement both Io<5>
and Io<7> at the same time, but I don't think it makes sense for a
single type to implement Io with different minimum sizes.
> /// Returns the base address of this mapping.
> - #[inline]
> - pub fn addr(&self) -> usize {
> - self.0.addr()
> - }
> + fn addr(&self) -> usize;
>
> /// Returns the maximum size of this mapping.
> - #[inline]
> - pub fn maxsize(&self) -> usize {
> - self.0.maxsize()
> - }
> -
> - #[inline]
> - const fn offset_valid<U>(offset: usize, size: usize) -> bool {
> - let type_size = core::mem::size_of::<U>();
> - if let Some(end) = offset.checked_add(type_size) {
> - end <= size && offset % type_size == 0
> - } else {
> - false
> - }
> - }
> + fn maxsize(&self) -> usize;
>
> + /// Returns the absolute I/O address for a given `offset`.
> + /// Performs runtime bounds checks using [`offset_valid`]
> #[inline]
> fn io_addr<U>(&self, offset: usize) -> Result<usize> {
> - if !Self::offset_valid::<U>(offset, self.maxsize()) {
> + if !offset_valid::<U>(offset, self.maxsize()) {
> return Err(EINVAL);
> }
>
> @@ -217,50 +215,197 @@ fn io_addr<U>(&self, offset: usize) -> Result<usize> {
> self.addr().checked_add(offset).ok_or(EINVAL)
> }
>
> + /// Returns the absolute I/O address for a given `offset`,
> + /// performing compile-time bound checks.
> #[inline]
> fn io_addr_assert<U>(&self, offset: usize) -> usize {
> - build_assert!(Self::offset_valid::<U>(offset, SIZE));
> + build_assert!(offset_valid::<U>(offset, SIZE));
>
> self.addr() + offset
> }
>
> - define_read!(read8, try_read8, readb -> u8);
> - define_read!(read16, try_read16, readw -> u16);
> - define_read!(read32, try_read32, readl -> u32);
> + /// Infallible 8-bit read with compile-time bounds check.
> + fn read8(&self, _offset: usize) -> u8 {
> + !0
> + }
> +
> + /// Infallible 16-bit read with compile-time bounds check.
> + fn read16(&self, _offset: usize) -> u16 {
> + !0
> + }
> +
> + /// Infallible 32-bit read with compile-time bounds check.
> + fn read32(&self, _offset: usize) -> u32 {
> + !0
> + }
> +
> + /// Infallible 64-bit read with compile-time bounds check (64-bit only).
> + #[cfg(CONFIG_64BIT)]
> + fn read64(&self, _offset: usize) -> u64 {
> + !0
> + }
> +
> + /// Fallible 8-bit read with runtime bounds check.
> + fn try_read8(&self, _offset: usize) -> Result<u8> {
> + Err(ENOTSUPP)
> + }
> +
> + /// Fallible 16-bit read with runtime bounds check.
> + fn try_read16(&self, _offset: usize) -> Result<u16> {
> + Err(ENOTSUPP)
> + }
> +
> + /// Fallible 32-bit read with runtime bounds check.
> + fn try_read32(&self, _offset: usize) -> Result<u32> {
> + Err(ENOTSUPP)
> + }
> +
> + /// Fallible 64-bit read with runtime bounds check (64-bit only).
> + #[cfg(CONFIG_64BIT)]
> + fn try_read64(&self, _offset: usize) -> Result<u64> {
> + Err(ENOTSUPP)
> + }
> +
> + /// Infallible 8-bit write with compile-time bounds check.
> + fn write8(&self, _value: u8, _offset: usize) {
> + ()
> + }
> +
> + /// Infallible 16-bit write with compile-time bounds check.
> + fn write16(&self, _value: u16, _offset: usize) {
> + ()
> + }
> +
> + /// Infallible 32-bit write with compile-time bounds check.
> + fn write32(&self, _value: u32, _offset: usize) {
> + ()
> + }
> +
> + /// Infallible 64-bit write with compile-time bounds check (64-bit only).
> + #[cfg(CONFIG_64BIT)]
> + fn write64(&self, _value: u64, _offset: usize) {
> + ()
> + }
> +
> + /// Fallible 8-bit write with runtime bounds check.
> + fn try_write8(&self, value: u8, offset: usize) -> Result;
> +
> + /// Fallible 16-bit write with runtime bounds check.
> + fn try_write16(&self, value: u16, offset: usize) -> Result;
> +
> + /// Fallible 32-bit write with runtime bounds check.
> + fn try_write32(&self, value: u32, offset: usize) -> Result;
> +
> + /// Fallible 64-bit write with runtime bounds check (64-bit only).
> + #[cfg(CONFIG_64BIT)]
> + fn try_write64(&self, _value: u64, _offset: usize) -> Result {
> + Err(ENOTSUPP)
> + }
Why are there default implementations for all of these trait methods? I
would suggest not providing any default implementations at all.
Alice
next prev parent reply other threads:[~2025-10-31 9:07 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-30 15:48 [PATCH v3 0/5] rust: pci: add config space read/write support Zhi Wang
2025-10-30 15:48 ` [PATCH v3 1/5] rust: io: factor common I/O helpers into Io trait Zhi Wang
2025-10-31 9:07 ` Alice Ryhl [this message]
2025-10-31 12:48 ` Zhi Wang
2025-10-31 12:55 ` Danilo Krummrich
2025-10-30 15:48 ` [PATCH v3 2/5] rust: io: factor out MMIO read/write macros Zhi Wang
2025-10-30 15:48 ` [PATCH v3 3/5] rust: pci: add a helper to query configuration space size Zhi Wang
2025-10-30 16:51 ` Bjorn Helgaas
2025-10-31 12:16 ` Zhi Wang
2025-10-31 12:46 ` Danilo Krummrich
2025-10-30 15:48 ` [PATCH v3 4/5] rust: pci: add config space read/write support Zhi Wang
2025-10-31 12:48 ` Danilo Krummrich
2025-10-31 12:50 ` Zhi Wang
2025-10-30 15:48 ` [PATCH v3 5/5] sample: rust: pci: add tests for config space routines Zhi Wang
2025-10-31 12:50 ` Danilo Krummrich
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=aQR8OPVnU_fPJTCI@google.com \
--to=aliceryhl@google.com \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=alex.gaynor@gmail.com \
--cc=aniketa@nvidia.com \
--cc=ankita@nvidia.com \
--cc=bhelgaas@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=cjia@nvidia.com \
--cc=dakr@kernel.org \
--cc=gary@garyguo.net \
--cc=helgaas@kernel.org \
--cc=jhubbard@nvidia.com \
--cc=joelagnelf@nvidia.com \
--cc=kwankhede@nvidia.com \
--cc=kwilczynski@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=markus.probst@posteo.de \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=smitra@nvidia.com \
--cc=targupta@nvidia.com \
--cc=tmgross@umich.edu \
--cc=zhiw@nvidia.com \
--cc=zhiwang@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.