Commit Graph

1603 Commits

Author SHA1 Message Date
Danilo Krummrich
ddca0cd800 rust: serdev: use ThisModule::as_ptr() instead of field access
The THIS_MODULE series [1] applied to rust-next moved ThisModule from
lib.rs into a module.rs submodule, making the tuple struct field private
outside the module. This breaks the module.0 field access in serdev in
driver-core-next.

Update the call to __serdev_device_driver_register() to use the public
module.as_ptr() accessor to fix the build.

Link: https://lore.kernel.org/all/20260811-fix-fops-owner-v10-0-7e71776f9dbe@linux.dev/ [1]
Closes: https://lore.kernel.org/all/DKNAS52KYWLD.M15VEC6U0F6R@kernel.org/
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Markus Probst <markus.probst@posteo.de>
Link: https://patch.msgid.link/20260813152444.514580-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-14 01:05:46 +02:00
Danilo Krummrich
dbaafe9cc5 Merge tag 'v7.2-rc7' into driver-core-next
We need the driver-core fixes in here as well to build on top of.

Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-10 01:20:05 +02:00
Linus Torvalds
361efac9e9 Merge tag 'driver-core-7.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core
Pull driver core fixes from Danilo Krummrich:

 - Fix Rust build failure on s390 by gating ioremap() / iounmap()
   helpers and the io::mem module on CONFIG_HAS_IOMEM; gate affected
   doctests as well.

 - Add missing kernel-doc for show_const / store_const union members in
   struct device_attribute.

* tag 'driver-core-7.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core:
  rust: io: gate ioremap doctests on CONFIG_HAS_IOMEM
  rust: io: gate ioremap/iounmap on CONFIG_HAS_IOMEM
  driver core: add missing kernel-doc for union members
2026-08-08 07:13:29 -07:00
Ethan Plant
56c193a5cb rust: pci: Mark Device refcount methods inline
When building the kernel, the following Rust symbols are generated:
$ nm vmlinux | grep ' _R' | rustfilt | grep -E 'pci::Device.*(inc_ref|dec_ref)'
... T <kernel::pci::Device as kernel::sync::aref::AlwaysRefCounted>::dec_ref
... T <kernel::pci::Device as kernel::sync::aref::AlwaysRefCounted>::inc_ref

These Rust symbols are trivial wrappers around pci_dev_put() and
pci_dev_get(), respectively. It doesn't make sense to go through a
trivial wrapper for these functions, so mark them inline.

Suggested-by: Alice Ryhl <aliceryhl@google.com>
Link: https://github.com/Rust-for-Linux/linux/issues/1145
Signed-off-by: Ethan Plant <plant.ethan@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260804-inline-wrappers-v1-1-16916db867e5@gmail.com
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-06 23:28:25 +02:00
Danilo Krummrich
f88db65aec rust: io: gate ioremap doctests on CONFIG_HAS_IOMEM
The doc examples in io.rs and devres.rs directly call
bindings::ioremap() and bindings::iounmap(), which do not exist when
CONFIG_HAS_IOMEM is not set. This causes build failures with
CONFIG_RUST_KERNEL_DOCTESTS=y on such configurations (e.g. s390
allnoconfig).

Gate the affected doctests with `#![cfg(CONFIG_HAS_IOMEM)]` so they are
skipped when IOMEM is unavailable.

Fixes: 3f70ebe638 ("s390: Enable Rust support")
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Link: https://patch.msgid.link/20260805212920.1996937-2-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-06 16:05:50 +02:00
Danilo Krummrich
4f5f23846d rust: io: gate ioremap/iounmap on CONFIG_HAS_IOMEM
s390 does not provide ioremap()/iounmap() when CONFIG_HAS_IOMEM is not
set (which requires CONFIG_PCI on that architecture). This causes a
build failure with Rust enabled on e.g. s390 allnoconfig:

	In file included from rust/helpers/helpers.c:68:
	rust/helpers/io.c:8:9: error: call to undeclared function 'ioremap'; ISO C99 and later do not support implicit function declarations
	      [-Wimplicit-function-declaration]
	    8 |         return ioremap(offset, size);
	      |                ^
	rust/helpers/io.c:19:2: error: call to undeclared function 'iounmap'; ISO C99 and later do not support implicit function declarations
	      [-Wimplicit-function-declaration]
	   19 |         iounmap(addr);

Guard the C helpers behind #ifdef CONFIG_HAS_IOMEM and cfg-gate the Rust
io::mem module, such that IoMem, ExclusiveIoMem and IoRequest are not
available without CONFIG_HAS_IOMEM.

Note that the C API is inconsistent about this. For instance,
devm_ioremap() has no stub and produces a link failure without
CONFIG_HAS_IOMEM, whereas devm_platform_ioremap_resource() provides an
inline stub returning -EINVAL.

The approach taken here (compile-time gating) matches the former, which
is slightly more appropriate since any driver performing MMIO currently
requires CONFIG_HAS_IOMEM.

Ideally, s390 should provide ioremap()/iounmap() stubs unconditionally
(as UML already does), removing the need for any config gating as
discussed in [1]; a follow-up patch for s390 is expected.

Cc: Arnd Bergmann <arnd@arndb.de>
Reported-by: Miguel Ojeda <ojeda@kernel.org>
Closes: https://lore.kernel.org/all/20260803180931.97202-1-ojeda@kernel.org [1]
Fixes: 3f70ebe638 ("s390: Enable Rust support")
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Link: https://patch.msgid.link/20260805212920.1996937-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-06 16:05:50 +02:00
Danilo Krummrich
98c63ce4d7 rust: irq: make Registration compatible with lifetime-bound drivers
Adapt the IRQ registration to work with the Higher-Ranked Lifetime Types
(HRT) device driver architecture introduced in commit 2c7c659336
("Merge patch series "rust: device: Higher-Ranked Lifetime Types for
device drivers"").

With HRT, driver structs carry a lifetime parameter tied to the device
binding scope, allowing device resources such as pci::Bar<'bar> to be
held directly rather than through Devres indirection. However, the IRQ
abstraction required Handler: Sync + 'static, preventing handlers from
embedding lifetime-parameterized resources.

Remove the 'static bound from Handler and ThreadedHandler and replace
the Devres<RegistrationInner> indirection with direct request_irq() /
free_irq() calls in the constructor and PinnedDrop.  Registration<'a, T>
stores the IrqRequest<'a>, which structurally ties it to the device
binding scope.

Also remove the &Device<Bound> parameter from the handler callbacks,
since handlers that need device access can embed it in their own type.

IRQ handlers can now directly own device resources:

	struct IrqHandler<'irq> {
	    bar: pci::Bar<'irq, BAR_SIZE>,
	}

	impl irq::Handler for IrqHandler<'_> {
	    fn handle(&self) -> IrqReturn {
	        let stat = self.bar.read(regs::STAT);
	        ...
	    }
	}

This eliminates the indirection previously required for IRQ handlers to
access device resources and aligns with the broader goal of expressing
every registration scoped to a driver binding through compile-time
lifetime bounds.

Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260719153631.559341-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-04 23:30:34 +02:00
Gary Guo
928369abdd rust: net/phy: remove expansion from doc
The expansion serves little purpose and it can easily diverge.

Acked-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260629-id_info-v2-5-56fccbe9c5ef@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-03 22:52:51 +02:00
Younes Akhouayri
5391b147d9 rust: dma: return zero for Coherent reads past EOF
Coherent<T>::write_to_slice() calculates a zero-byte copy when the file
offset is beyond the allocation, but still calls
UserSliceWriter::write_dma(). The latter rejects offsets beyond the
allocation even when the copy length is zero, so a debugfs read past EOF
returns -ERANGE.

Return before calling write_dma() when the offset is at or beyond the
allocation, matching simple_read_from_buffer() EOF semantics.

Fixes: 0168185139 ("rust: dma: implement BinaryWriter for Coherent<[u8]>")
Cc: stable@vger.kernel.org
Link: https://rust-for-linux.zulipchat.com/#narrow/channel/291566-Library/topic/.E2.9C.94.20Possible.20past-EOF.20bug.20in.20Coherent.3CT.3E.3A.3Awrite_to_slice/near/611677095
Signed-off-by: Younes Akhouayri <git@younes.io>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Onur Özkan <work@onurozkan.dev>
Link: https://patch.msgid.link/20260730-fix-dma-coherent-eof-v2-1-8aff21054afa@younes.io
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-03 22:48:03 +02:00
Alexandre Courbot
2230d38828 rust: io: register: use path fragment for alias destination
The destination of an alias is always another register, i.e. a `struct`
type. Replace the `ident` fragment with a `path` one in the internal
rules: `path` is more accurate, and allows referencing registers using a
qualified path instead of only identifiers visible from the current
module.

This covers all aliases, except the relative register ones which are to
be removed soon.

The public rule cannot be updated yet because a `+` can still be matched
after the alias; add a TODO item to update it after relative registers
are removed.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://patch.msgid.link/20260724-registers_fix-v2-3-a0fb58b02185@nvidia.com
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-03 22:30:32 +02:00
Alexandre Courbot
78e9b43892 rust: io: register: remove unused rule arguments
A few arguments passed to internal rules are never used and just add
unneeded complexity. Remove them to simplify the rules a bit.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://patch.msgid.link/20260724-registers_fix-v2-2-a0fb58b02185@nvidia.com
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-03 22:30:32 +02:00
Alexandre Courbot
ebb314763f rust: io: register: dispatch shortcut rules internally
A couple of shortcut rules redispatch an already normalized declaration
through the public register! entry point. This is unneeded - the public
rule should only be invoked by users.

Dispatch directly to the appropriate internal @reg rule instead.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260724-registers_fix-v2-1-a0fb58b02185@nvidia.com
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-03 22:30:32 +02:00
Josef Ippisch
68ac45aabe rust: debugfs: remove unsafe blocks from traits impl for Vec
The previous implementation used an `unsafe` block to manually cast Vec's
slice to a &[u8] using `core::slice::from_raw_parts`.  Instead, the
implementation can be implemented in safe rust using zerocopy's trait
functions `as_bytes()` and `as_mut_bytes()`, respectively, and making use
of deref coercion to implicitly cast Vec to &[T] as `FromBytes` and
`IntoBytes` automatically are implemented on [T] when they are implemented
on T.

Signed-off-by: Josef Ippisch <josef.ippisch.dev@mailbox.org>
Link: https://patch.msgid.link/20260728-migrate-binarywriter-to-zerocopy-intobytes-v2-2-0a4ec1d3ead4@mailbox.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-31 11:08:29 +02:00
Josef Ippisch
6e33dee41d rust: debugfs: migrate debugfs traits requirements to zerocopy
Migrate `BinaryWriter` and `BinaryReaderMut`'s default implementation's
requirements on T from `kernel::transmute` traits to `zerocopy` traits.

The additional `zerocopy::Immutable` requirement on `BinaryWriter` does not
further restrict the types in practice but is rather a more explicit
requirement (that the type does not have interior mutability) and is
required by zerocopy for the `as_bytes()` function.

Suggested-by: Joshua Liebow-Feeser <joshlf@google.com>
Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://github.com/Rust-for-Linux/linux/issues/975
Link: https://github.com/Rust-for-Linux/linux/issues/1241
Signed-off-by: Josef Ippisch <josef.ippisch.dev@mailbox.org>
Link: https://patch.msgid.link/20260728-migrate-binarywriter-to-zerocopy-intobytes-v2-1-0a4ec1d3ead4@mailbox.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-31 11:08:29 +02:00
Gary Guo
17fcdecb14 rust: driver: remove duplicate ID table
Previously, `IdArray` contains both device ID table and info table so we
keep a separate copy for MODULE_DEVICE_TABLE for hotplug (which needs to be
just the device ID table). With the info being changed to be carried via
pointers, `IdArray` is now layout compatible with raw ID table and hence
there is no longer a need to keep the distinction.

Deduplicate the code, and remove the redundant copy for hotplug purpose by
just giving the `IdArray` instance a proper symbol name.

While at it, also update the macro to use `::core::line!()` instead of just
`line!()`.

Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20260629-id_info-v2-10-56fccbe9c5ef@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-30 22:50:15 +02:00
Gary Guo
2c5d17cdc4 rust: driver: remove open-coded matching logic
With device ID info now including pointers instead of indices, the
open-coded ACPI/OF matching is no longer needed and can be replaced with
`device_get_match_data`.

With the removal of open-coded matching, the exposed functions and helpers
are also removed; this effectively reverts most of commit 2690d07158
("rust: ACPI: fix missing match data for PRP0001").

Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20260629-id_info-v2-9-56fccbe9c5ef@garyguo.net
[ Consider the serdev code merged in the meantime. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-30 22:50:15 +02:00
Gary Guo
0b76335e8f rust: driver: store pointers in DeviceId
The common practice in C drivers is to store pointers into `driver_data`
field of device IDs. The Rust code is however currently storing indices
into the fields and then carry a side table that maps the index to
pointers.

It is much simpler to just have `DeviceId` carry the pointer like C code
does. However, just doing so naively would cause a "pointers cannot be cast
to integers during const eval" error, as kernel_ulong_t does not have
provenance while pointers do, and Rust forbids `expose_provenance` during
consteval.

Work around this limitation by wrapping raw IDs in `MaybeUninit`.
`MaybeUninit` is allowed to host arbitrary bytes with or without
provenance, so we can just then use `unsafe` to store a pointer with
provenance there. This has the same effect as changing the C-side
definition to use `void*` instead of `kernel_ulong_t`, but without actually
changing the C side.

Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20260629-id_info-v2-8-56fccbe9c5ef@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-30 22:50:15 +02:00
Gary Guo
0deeb4222d rust: driver: remove $module_table_name from module_device_table
Wrap the generated code in a `const _: ()` block to avoid symbol conflict.
This removes the need of creating a new identifier.

Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20260629-id_info-v2-7-56fccbe9c5ef@garyguo.net
[ Consider the serdev code merged in the meantime. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-30 22:50:15 +02:00
Gary Guo
1d92f2e8b8 rust: driver: centralize device ID handling
Move the `IdArray` creation from individual buses to be handled by shared
code in `device_id.rs`.

Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20260629-id_info-v2-6-56fccbe9c5ef@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-30 22:50:15 +02:00
Gary Guo
c7b6e07f83 rust: usb: use Option<&IdInfo> for device ID info
It is possible that ID without driver_data will be passed to the driver,
e.g. `new_id` is used to dynamically create a new ID without data.
Therefore, the driver must be able to handle the case where `driver_data`
is 0. Thus, update the `probe` functions to get `Option`.

The current code cannot tell if the info does not exist or is the first
entry; however this will be achievable once the code is updated to use a
`&'static IdInfo` pointer instead of indices.

Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20260629-id_info-v2-4-56fccbe9c5ef@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-30 16:42:34 +02:00
Gary Guo
4fcbf7f1e4 rust: pci: use Option<&IdInfo> for device ID info
It is possible that `pci_device_id_any` will be passed to the driver, e.g.
`driver_override` is used on the device. Therefore, the driver must be able
to handle the case where `driver_data` is 0. Thus, update the `probe`
functions to get `Option`.

The current code cannot tell if the info does not exist or is the first
entry; however this will be achievable once the code is updated to use a
`&'static IdInfo` pointer instead of indices.

Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20260629-id_info-v2-3-56fccbe9c5ef@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-30 16:42:34 +02:00
Gary Guo
e49f626ef5 rust: driver: simplify IdArray::new_without_index
This method can very easily construct the `IdArray` on its own without
delegating to `Self::build`. Doing so also simplifies the phy device table
macro because it does not need to construct tuples anymore.

This also allows simplification of `new` and `build` which removes the
`unsafe`.

Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20260629-id_info-v2-2-56fccbe9c5ef@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-30 16:42:34 +02:00
Gary Guo
3474bbba4d rust: driver: remove IdTable::id
This is unused.

Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20260629-id_info-v2-1-56fccbe9c5ef@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-30 16:42:34 +02:00
Gary Guo
a1f1b3b478 rust: devres: use cast_pin_init instead of manual reimplementation
Remove the manual type-casting which is already available as
`cast_pin_init`.

Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260722-merge-init-v1-2-d4594de76538@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-27 22:29:34 +02:00
Markus Probst
99f59aa823 rust: add basic serial device bus abstractions
Implement the basic serial device bus abstractions required to write a
serial device bus device driver with or without the need for initial device
data. This includes the following data structures:

The `serdev::Driver` trait represents the interface to the driver.

The `serdev::Device` abstraction represents a `struct serdev_device`.

In order to provide the Serdev specific parts to a generic
`driver::Registration` the `driver::RegistrationOps` trait is
implemented by `serdev::Adapter`.

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Markus Probst <markus.probst@posteo.de>
Link: https://patch.msgid.link/20260718-rust_serdev-v16-1-5809384d2e1b@posteo.de
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-23 22:48:24 +02:00
Younes Akhouayri
01899cb7b9 rust: irq: fix C header path in module docs
The IRQ module documentation displays `include/linux/device.h`, while
the link points to `include/linux/interrupt.h`. The module wraps the IRQ
registration interfaces declared in `include/linux/interrupt.h`, so fix
the displayed header path.

Fixes: 1f54d5e5cd ("rust: irq: add irq module")
Link: https://github.com/Rust-for-Linux/linux/issues/1246
Signed-off-by: Younes Akhouayri <git@younes.io>
Link: https://patch.msgid.link/20260717-docs-irq-rustdoc-header-v1-1-36749192aa04@younes.io
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-21 00:48:45 +02:00
Gary Guo
c2d8b26205 rust: io: document const-offset requirement for infallible accessors
Due to the usage of `build_assert!` for address validity checking, these
accessors want constant offsets. Non-constant offsets can work but it
depend on compiler optimization levels, so it should be avoided.

Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://patch.msgid.link/20260716142545.3622278-1-gary@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-21 00:48:25 +02:00
Gary Guo
f7acb19abc rust: device: make lifetime on Core and CoreInternal invariant
Currently the lifetime on `Core` and `CoreInternal` is covariant. This
means that they can be coerced into shorter living lifetimes. On `probe`
function, signature has `&'bound Device<Core<'a>>`; the type's wellformness
would imply `'a: 'bound` and thus the type can be coerced `&'bound
Device<Core<'bound>>`, defeating the purpose of having the lifetime bound
to prevent users of the `Core` type to escape the function.

Fix this by making the lifetime invariant, so the coercion is impossible.
The lifetime here only needs to be "branded" so it does not coerce or unify
with other lifetimes, so we do not need to ensure `'bound: 'a`.

This requires modifying `nova-core` which relies on this implied bound due
to pre-2024 capture rule. The "use" bound can be removed if built with
edition 2024.

Fixes: 24799831d6 ("rust: device: make Core and CoreInternal lifetime-parameterized")
Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260713201455.640151-1-gary@kernel.org
[ Fixup the debugfs sample to use an explicit lifetime instead of
  Core<'_>. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-21 00:46:17 +02:00
FUJITA Tomonori
880c43b185 rust: time: fix as_micros_ceil() to round correctly for negative Delta
The ceiling-division idiom `(n + d - 1) / d` only produces the
correct result when `n` is non-negative.

For example, if n = -1000 (exactly -1us), the old code computed (-1000
+ 999) / 1000 == 0 instead of -1.

For negative n, truncating division already rounds towards positive
infinity, so no bias is needed in that case.

Fixes: fae0cdc123 ("rust: time: Introduce Delta type")
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
Acked-by: Andreas Hindborg <a.hindborg@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260713225235.3243480-1-tomo@flapping.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2026-07-18 19:07:35 +02:00
Danilo Krummrich
54b4b3aa7c rust: device: move drvdata_borrow() to InternalBoundContext
Move drvdata_borrow() from impl Device<CoreInternal<'a>> to
impl<Ctx: InternalBoundContext> Device<Ctx>, making it available from
both CoreInternal and BoundInternal contexts.

Fold drvdata_unchecked() (previously on Device<Bound>) directly into
drvdata_borrow(), since it was only called from there and the generic
context cannot resolve methods through the deref chain.

Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Reviewed-By: Markus Probst <markus.probst@posteo.de>
Link: https://patch.msgid.link/20260530132736.3298549-2-dakr@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-18 16:07:22 +02:00
Danilo Krummrich
807be7ee6f rust: device: add BoundInternal device context and InternalBoundContext trait
Add a new BoundInternal device context type for cases where bus
abstractions need access to internal device infrastructure, where
CoreInternal would not be justified.

Introduce the InternalBoundContext marker trait, implemented by both
CoreInternal and BoundInternal, to allow methods that require internal
bus abstraction access to a bound device to be generic over both
contexts.

The deref hierarchy now has two branches:
  - CoreInternal<'a> => Core<'a> => Bound => Normal
  - BoundInternal => Bound => Normal

Update impl_device_context_deref! and impl_device_context_into_aref!
macros to emit the BoundInternal => Bound deref and the corresponding
ARef conversion.

Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Reviewed-By: Markus Probst <markus.probst@posteo.de>
Link: https://patch.msgid.link/20260530132736.3298549-1-dakr@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-18 16:07:22 +02:00
Miguel Ojeda
3fadfb9362 rust: firmware: avoid UB in example by passing parameter
The `Firmware` example crafts an `ARef<Device>` using a null pointer,
which breaks the safety requirements of `Device::get_device()`.

Instead, pass an `ARef` via a parameter, which is simpler, avoids UB
and removes an `unsafe` block.

Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260711180231.229525-1-ojeda@kernel.org
[ Also drop the second superfluous empty line. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-17 15:44:44 +02:00
Alice Ryhl
a19bda861b rust: device: avoid trailing ; in printing macros
These macros are used like expressions, so they should not emit a
semicolon. This is being turned into a hard error in a future release of
Rust.

    error: trailing semicolon in macro used in expression position
      --> drivers/gpu/nova-core/firmware/fsp.rs:79:34
       |
    79 |                 .inspect_err(|_| dev_err!(dev, "FMC firmware missing '{}' section\n", name))
       |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       |
       = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
       = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
       = note: this error originates in the macro `dev_err` (in Nightly builds, run with -Z macro-backtrace for more info)

[ I was doubly surprised since upstream made it a deny-by-default lint
  a year ago for Rust 1.91.0, and yet we didn't see it; plus I hadn't
  seen this in my CI even yesterday.

  It turns out this just landed into today's nightly (nightly-2026-07-16,
  using upstream commit d0babd8b6):

    Link: https://github.com/rust-lang/rust/pull/159222

  which says:

    "The `semicolon_in_expressions_from_macros` lint previously
     suppressed warnings about non-local macros. This masks
     a lint that will subsequently become a hard error."

  So that explains it. And this is the PR that will make it a hard error
  at some point in the future:

    Link: https://github.com/rust-lang/rust/pull/159218

  Thus starting with Rust 1.99.0 (expected 2026-10-01), we will be
  seeing the deny-by-default lint above, so clean it up already.

    - Miguel ]

Cc: stable@vger.kernel.org # Needed in 6.18.y and later.
Link: https://github.com/rust-lang/rust/issues/79813
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: https://github.com/rust-lang/rust/pull/159218
Link: https://github.com/rust-lang/rust/pull/159222
Link: https://patch.msgid.link/20260716-device-trail-semicolon-v1-1-f48e9dcfae15@google.com
[ Fixed typo. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2026-07-16 23:40:54 +02:00
Danilo Krummrich
a10639966f rust: devres: ensure revocation is complete before device finishes unbinding
Now that the revocation Completion is in place, also address the
symmetric case. When Devres::drop() wins the is_available swap and the
devres callback loses, the callback returns to devres_release_all()
without waiting. This means device unbinding can complete while
Devres::drop() is still executing drop_in_place() on another CPU, which
is a problem if T's destructor accesses device state.

Make the synchronization bidirectional. Whichever side performs
drop_in_place() signals the Completion, and the other side waits.

This does not reintroduce the nested Devres deadlock fixed by commit
ba268514ea ("rust: devres: fix race condition due to nesting"),
because that deadlock was caused by drop waiting for the release
callback to return (the old 'devm' Completion). Here, both sides only
wait for drop_in_place() to finish, which completes within the current
call chain. The Arc<Inner<T>> keeps the Inner allocation alive
independently.

Cc: stable@vger.kernel.org
Fixes: ba268514ea ("rust: devres: fix race condition due to nesting")
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260628200304.2365598-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-14 00:57:19 +02:00
Danilo Krummrich
acc516dfa1 rust: devres: fix race between concurrent revokers
There is a potential race condition when two paths try to revoke a
Devres concurrently.

The driver core's devres_release_all() calls Revocable::revoke() via the
release callback, while Devres::drop() calls revoke_nosync() on another
CPU.

The revoker that does not claim the is_available swap returns
immediately, but the revoker that did may still be executing
drop_in_place() on the inner data. This can cause a use-after-free when
the other revoker's caller proceeds to drop adjacent resources that
drop_in_place() still references (e.g., Devres<DmaMappedSgt> racing with
SGTable freeing the backing sg_table and pages).

Fix this by adding a Completion. The release callback signals the
Completion after revoke() finishes, and Devres::drop() waits for it when
it loses the is_available swap. This ensures the wrapped object is fully
torn down before Devres::drop() returns.

Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/dri-devel/20260612202841.2577C1F000E9@smtp.kernel.org/
Fixes: 05aa6fb1c2 ("rust: scatterlist: Add abstraction for sg_table")
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260628174451.2275679-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-14 00:57:19 +02:00
Danilo Krummrich
b07fc8d60b Merge patch series "rust: I/O type generalization and projection"
Gary Guo <gary@garyguo.net> says:

This series presents a major rework of I/O types, as a summary:

- Make I/O regions typed. The existing untyped region still exists
  with a dynamically sized `Region` type.

- Create I/O view types to represent subregion of a full I/O region mapped.
  A projection macro is added to allow safely create such subviews.

- Split I/O traits, make I/O views play a central role, avoid
  duplicate monomorphization and less `unsafe` code.

- Add a `SysMem` backend, and make `Coherent` implement `Io`.

- Add copying methods (memcpy_{from,to}io and friends).

This series generalize `Mmio` type from just an untyped region to typed
representations (so `MmioRaw<T>` is `__iomem *T`). This allows us to remove
the `IoKnownSize` trait; the information is sourced from just the pointer
from the `KnownSize` trait instead.

Building on top of that, `Mmio` and `ConfigSpace` have been converted to
typed views of I/O regions rather than just a big chunk of untyped I/O
memory. These changes made it possible to implement `Io` trait for
`Coherent<T>`.

Shared system memory, `SysMem` is also added to the series, given it
similarity in implementation compared to `Coherent`. In fact, the series
use `SysMem` to implement `Coherent`'s I/O methods.

Built on these generalization, this series add `io_project!()`.
`io_project!()` performs a safe way to project a bigger view to a small
subviews, and some Nova code has been converted in this series to
demonstrate cleanups possible with this addition.

New `io_read!()`, `io_write!()` has been added that supersedes
`dma_read!()`, `dma_write!()` macro. Although, they work for primitives
only (to be exact, types that the backend is `IoCapable` of).
One feature that was lost from the old `dma_read!()` and `dma_write!()`
series was the ability to read/write a large structs. However, the
semantics was unclear to begin with, as there was no guarantee about their
atomicity even for structs that were small enough to fit in u32.

Suggested-by: Danilo Krummrich <dakr@kernel.org>
Link: https://rust-for-linux.zulipchat.com/#narrow/channel/288089-General/topic/Generic.20I.2FO.20backends/near/571198078
Link: https://patch.msgid.link/20260706-io_projection-v6-0-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-13 23:50:39 +02:00
Danilo Krummrich
a56a92be1f Merge patch series "ForLt/CovariantForLt split, auxiliary closure API and DevresLt"
Danilo Krummrich <dakr@kernel.org> says:

The ForLt trait currently guarantees covariance, which allows safe
lifetime shortening via cast_ref(). However, some types (e.g. those
containing Mutex<&'bound T>) are invariant over their lifetime parameter
and cannot safely use cast_ref().

This series splits ForLt into two traits:

  - ForLt: base trait for all lifetime-parameterized types, providing
    only the Of<'a> GAT.

  - CovariantForLt: unsafe subtrait that guarantees covariance,
    providing a safe cast_ref() method.

For invariant types, a closure-based API (registration_data_with()) is
added to the auxiliary subsystem. The closure's HRTB prevents the caller
from choosing a concrete lifetime, which would be unsound for invariant
types.

On top of that, this series adds DevresLt<F: ForLt>, a thin wrapper
around Devres<F::Of<'static>> that shortens the stored 'static lifetime
back to the caller's borrow scope. DevresLt provides both closure-based
access (access_with/try_access_with for ForLt types) and direct
reference access (access/try_access for CovariantForLt types).

Also implement ForLt and CovariantForLt for Bar, IoMem and
ExclusiveIoMem, and update their into_devres() methods to return
DevresLt. Provide convenience type aliases DevresBar, DevresIoMem and
DevresExclusiveIoMem.

Link: https://patch.msgid.link/20260626183630.2585057-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-13 23:34:30 +02:00
Danilo Krummrich
7488dc14b0 rust: io: mem: return DevresLt from IoMem/ExclusiveIoMem::into_devres()
Implement ForLt and CovariantForLt for IoMem<'static, SIZE> and
ExclusiveIoMem<'static, SIZE> so that DevresLt can shorten the stored
'static lifetime back to the caller's borrow lifetime.

CovariantForLt is sound because both types only hold &'a Device<Bound>,
which is covariant over 'a.

Since DevresLt::new() handles the lifetime transmutation internally,
into_devres() no longer needs an explicit transmute to 'static.

Add DevresIoMem<SIZE> and DevresExclusiveIoMem<SIZE> type aliases.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://patch.msgid.link/20260626183630.2585057-8-dakr@kernel.org
[ Add default SIZE parameter to DevresIoMem. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 19:47:00 +02:00
Danilo Krummrich
e7e6bf5af8 rust: pci: return DevresLt from Bar::into_devres()
Implement ForLt and CovariantForLt for Bar<'static, SIZE> so that
DevresLt can shorten the stored 'static lifetime back to the caller's
borrow lifetime.

CovariantForLt is sound because Bar<'a, SIZE> only holds &'a
Device<Bound>, which is covariant over 'a.

Since DevresLt::new() handles the lifetime transmutation internally,
into_devres() no longer needs an explicit transmute to Bar<'static>.

Add a DevresBar<SIZE> type alias for convenience.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://patch.msgid.link/20260626183630.2585057-7-dakr@kernel.org
[ Add default SIZE parameter to DevresBar. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 19:45:40 +02:00
Danilo Krummrich
b85f672a3e rust: devres: add DevresLt for ForLt-aware device resource access
Devres<T> stores resources as T and returns &'a T from access(). For
lifetime-parameterized types like Bar<'a, SIZE> that are transmuted to
'static for storage, this exposes the synthetic 'static lifetime to
callers -- any method on the stored type that returns a reference with
its lifetime parameter would yield a &'static reference, which is
unsound.

Add DevresLt<F: ForLt>, a thin wrapper around Devres<F::Of<'static>>
that shortens the stored 'static lifetime to the caller's borrow
lifetime in all access methods.

DevresLt::new() is unsafe because the caller must guarantee that the
data remains valid for the device's full bound scope; the internal
transmute from F::Of<'a> to F::Of<'static> would otherwise allow
use-after-free.

Two access patterns are provided:

- CovariantForLt types get direct-reference accessors (access,
  try_access) that return shortened references via
  CovariantForLt::cast_ref.

- Plain ForLt types use closure-based accessors (access_with,
  try_access_with) whose universally quantified lifetime prevents
  callers from smuggling in concrete short-lived references.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://patch.msgid.link/20260626183630.2585057-6-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 19:44:38 +02:00
Danilo Krummrich
491784c54c rust: auxiliary: add registration_data_with() for ForLt types
Add registration_data_with() taking a for<'a> closure that receives
Pin<&'a F::Of<'a>>, which works with any ForLt type. Taking a for<'a>
closure rather than returning a direct reference prevents callers from
choosing a concrete lifetime for the data, which is required for
soundness with non-covariant ForLt types.

Extract the common null-check, TypeId-check and KBox-borrow logic into a
private registration_data_pinned() helper shared by both
registration_data_with() and the existing registration_data().

Relax Registration's bound from CovariantForLt to ForLt so that
non-covariant types can be registered.

Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://patch.msgid.link/20260626183630.2585057-4-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 19:44:38 +02:00
Danilo Krummrich
1b56056294 rust: types: introduce ForLt base trait for CovariantForLt
Add a new ForLt trait as a base for CovariantForLt:

  - ForLt (non-unsafe): represents a type generic over a lifetime, with
    no covariance guarantee.

  - CovariantForLt (unsafe): becomes a subtrait of ForLt that
    additionally proves the type is covariant over its lifetime
    parameter, providing a safe cast_ref() method.

This split allows non-covariant types (e.g. types behind a Mutex) to
implement ForLt and participate in DevresLt / registration data patterns
that use HRTB closures for sound access, without requiring a covariance
proof that would fail to compile.

Both macros share the UnsafeForLtImpl helper type, distinguished by
a const generic N: ForLt! emits N = 0 (no covariance proof),
CovariantForLt! emits N = 1 (with compile-time covariance proof).

Reviewed-by: Gary Guo <gary@garyguo.net>
Acked-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://patch.msgid.link/20260626183630.2585057-3-dakr@kernel.org
[ Merge ForLt pub use, inline resolve_hrt/ty_static, add intra-doc
  links. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 19:42:03 +02:00
Danilo Krummrich
2c91f57e81 rust: types: rename ForLt to CovariantForLt
Rename ForLt to CovariantForLt to prepare for the introduction of a new
ForLt base trait that does not require covariance.

The existing ForLt trait requires covariance, which enables the safe
cast_ref() method. This rename preserves the same semantics under a more
precise name, making room for a weaker ForLt trait in a subsequent
commit.

No functional change.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Acked-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://patch.msgid.link/20260626183630.2585057-2-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 18:35:47 +02:00
Gary Guo
11a4784f90 rust: io: implement IoSysMap
Add an enum as sum type for `Mmio` and `SysMem`. This serves similar
purpose of `iosys_map`. Thanks to Rust's type system, all of projection and
struct read/write can be handled by the generic I/O projection mechanism
(i.e. `io_project!`, `io_read!, `io_write!`) for free, and there is no need
to provide things like `iosys_map_rd_field` or `iosys_map_wr_field`. An
enum type also makes it very easy to construct or destruct.

This could be made more generic by implementing on a general purpose sum
type like `Either`; however this is kept specific unless a need arises that
warrants this to be generic over other I/O backends.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260706-io_projection-v6-20-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 18:09:04 +02:00
Gary Guo
e7219e53c5 rust: io: add copying methods
One feature that was lost from the old `dma_read!` and `dma_write!` when
moving to `io_read!` and `io_write!` was the ability to read/write a large
structs. However, the semantics was unclear to begin with, as there was no
guarantee about their atomicity even for structs that were small enough to
fit in u32. Re-introduce the capability in the form of copying methods.

    dma_read!(foo, bar) -> io_project!(foo, bar).copy_read()
    dma_write!(foo, bar, baz) -> io_project!(foo, bar).copy_write(baz)

Model these semantics after memcpy so user has clear expectation of lack of
atomicity. As an additional benefit of this change, this now works for MMIO
as well by mapping them to `memcpy_{from,to}io`.

For slices which is DST so the `copy_read` and `copy_write` API above can't
work, add `copy_from_slice` and `copy_to_slice` to copy from/to normal
memory.

Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://patch.msgid.link/20260706-io_projection-v6-19-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 18:09:04 +02:00
Gary Guo
6ff7d69b7e rust: dma: drop dma_read! and dma_write! API
The primitive read/write use case is covered by the `io_read!` and
`io_write!` macro. The non-primitive use case was finicky; they should
either be achieved using `CoherentBox` or `as_ref()/as_mut()` to assert the
lack of concurrent access, or should be using memcpy-like APIs to express
the non-atomic and tearable nature.

Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Link: https://patch.msgid.link/20260706-io_projection-v6-18-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 18:09:04 +02:00
Gary Guo
89814c42c1 rust: io: add read_val and write_val functions on Io
Provide `read_val` and `write_val` that allow I/O views to be accessed when
they're narrowed down to just views of primitives.

This is used to provide `io_read!` and `io_write!` macros, which are
generalized version of current `dma_read!` and `dma_write!` macro that work
for all types that implement `Io`.

Note though `io_read!` and `io_write!` only works if backend implements
`IoCapable` for the type; which is typically only implemented for
atomically accessible primitives. `dma_read!` and `dma_write!` currently
supports them via `read_volatile` and `write_volatile`; this can be
undesirable for aggregates as LLVM may turn them to multiple instructions
to access parts and re-assemble, even if they could be combined to a single
instruction. Thus, `io_read!()` and `io_write!()` does not fully replace
`dma_read!()` and `dma_write!()` in this scenario. The ability to
read/write aggregates (when atomicity is of no concern) is better served
with copying primitives (e.g. memcpy_{from,to}io).

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Link: https://patch.msgid.link/20260706-io_projection-v6-16-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 18:09:04 +02:00
Gary Guo
1d409d1e7a rust: io: implement a view type for Coherent
Implement a `CoherentView` type which is a view of `Coherent`. To be able
to give out DMA handles, the view type contains both CPU and DMA pointers,
and the projection method projects both at once.

Delegate most of the `Io` implementation to `SysMemBackend`. Provide a
method to erase the DMA handle and give out a `SysMem` view, if the user
does not need the `dma_handle`.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Link: https://patch.msgid.link/20260706-io_projection-v6-15-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 18:09:04 +02:00
Laura Nao
2fabff7807 rust: io: add I/O backend for system memory with volatile access
Add `SysMem`, an `Io` trait implementation for kernel virtual address
ranges. It uses volatile accessors to provide safe access to shared
memory that may be concurrently accessed by external hardware. Implement
`IoCapable` for `u8`, `u16`, `u32`, and `u64` (for 64-bit system).

This can be used instead of `Coherent` for cases where a different layer
takes care of mapping the system memory to the device (e.g. dma-buf or
GPUVM).

Signed-off-by: Laura Nao <laura.nao@collabora.com>
[ Rebased and adapted on top of I/O rework. - Gary ]
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Link: https://patch.msgid.link/20260706-io_projection-v6-14-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 18:09:04 +02:00
Gary Guo
1f989555fe rust: io: add projection macro and methods
Add an `io_project!()` macro to allow projection from `Io` to a subview of
it, using the pointer projection mechanism to perform compile-time checks.

For cases where type-casting is required, the `try_cast()` function may be
used where the size and alignment checks are performed at runtime.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Link: https://patch.msgid.link/20260706-io_projection-v6-13-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 18:09:04 +02:00