Commit Graph
1461816 Commits
Author SHA1 Message Date
Alexandre Courbot bb2d007399 gpu: nova-core: gsp: make use of FWSEC bootloader a property of the TU102 HAL
By being in the TU102 HAL, we already know that the GSP boot method is
the SEC2 Booter, so the only variable is whether the FWSEC bootloader is
used or not. Since `Chipset` also includes the variants that boot FSP,
querying it for that information introduces a potential code path (a
chipset that boots via FSP) that the current code doesn't handle.

Turn the use of the FWSEC bootloader into a property of the `Tu102` HAL,
and give GA102+ chipsets their own instance with that property set to
`false`. This removes the invalid code path and the only use of
`Chipset` is now to load the correct firmware files.

This also removes some uses of the `Chipset::needs_fwsec_bootloader`
method and prepares the ground for removing it.

Reviewed-by: Eliot Courtney <ecourtney@nvidia.com>
Link: https://patch.msgid.link/20260709-nova-bootcontext-v6-8-520cbf8b9b50@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
2026-07-15 16:00:52 -07:00
Alexandre Courbot 7567e62b9c gpu: nova-core: gsp: turn FWSEC execution into HAL method
Turn the `run_fwsec_frts` function into a method of `Tu102`. A following
patch will turn the "use FWSEC bootloader" property into a flag of the
TU102 HAL itself, and making this a method will allow the code to access
it instead of querying `Chipset`.

Reviewed-by: Eliot Courtney <ecourtney@nvidia.com>
Link: https://patch.msgid.link/20260709-nova-bootcontext-v6-7-520cbf8b9b50@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
2026-07-15 16:00:52 -07:00
Alexandre Courbot 436f3c4ac4 gpu: nova-core: gsp: fold TU102 unload bundle construction into HAL method
The construction of the unload bundle is currently a bit convoluted and
could be done in one function instead of two.

Additionally, turn that function into a method of `Tu102`. A following
patch will turn the "use FWSEC bootloader" property into a flag of the
TU102 HAL itself, and making this a method will allow the code to access
it instead of querying `Chipset`.

Reviewed-by: Eliot Courtney <ecourtney@nvidia.com>
Link: https://patch.msgid.link/20260709-nova-bootcontext-v6-6-520cbf8b9b50@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
2026-07-15 16:00:52 -07:00
Alexandre Courbot 92faa16f34 gpu: nova-core: gsp: centralize missing unload bundle warnings
The warning emitted when the unload bundle cannot be constructed is
valid regardless of the boot method, but it was local to `Tu102`. Move
it to `Gsp::boot` so it applies to all boot methods.

Reviewed-by: Eliot Courtney <ecourtney@nvidia.com>
Link: https://patch.msgid.link/20260709-nova-bootcontext-v6-5-520cbf8b9b50@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
2026-07-15 16:00:52 -07:00
Alexandre Courbot 3099edaaab gpu: nova-core: gsp: pass GspBootContext to unload methods
`GspBootContext` contains the resources required to boot the GSP. As it
turns out, this is also the context required for unloading it.

Reflect that fact by replacing the arguments of `Gsp::unload` and
`UnloadBundle::run` with the `GspBootContext`. This symmetry between
`Gsp::boot` and `Gsp::unload` will also be convenient when we want to
make these methods generic over the boot context corresponding to the
boot method used.

Reviewed-by: Eliot Courtney <ecourtney@nvidia.com>
Link: https://patch.msgid.link/20260709-nova-bootcontext-v6-4-520cbf8b9b50@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
2026-07-15 16:00:52 -07:00
Alexandre Courbot ebf164beb9 gpu: nova-core: gsp: replace BootUnloadGuard with local handlers
When adding the GSP unload capability, we introduced `BootUnloadGuard`
to automatically call `Gsp::unload` whenever an error occurred during
the boot process, in order to try to reset the GSP to a valid state.

This approach is not well-suited to the errors that may occur in HALs:
by definition, an error occurring in the HAL means that the GSP is not
booted; yet the first thing that `Gsp::unload` does is queue a shutdown
message to the GSP, which will inevitably result in a timeout when done
from a HAL.

Furthermore, `BootUnloadGuard` is problematic because it holds
additional references to the boot context, notably the `Falcon`s. These
extra references stand in the way of making some of the `Falcon`'s
methods mutable, since those methods would require exclusive access. As
this behavior is only needed in one place, introducing dedicated types
for it is distracting and unnecessary.

Thus, remove `BootUnloadGuard` and adopt a two-level error handling
strategy:

- HALs are free to handle their errors as they see fit (most likely, by
  running their unload bundle if it is ready by the time of the error),
- `Gsp::boot` uses a `ScopeGuard` that runs `Gsp::unload`, since the
  GSP should be up and running by the time `GspHal::boot` has returned.

Reviewed-by: Eliot Courtney <ecourtney@nvidia.com>
Link: https://patch.msgid.link/20260709-nova-bootcontext-v6-3-520cbf8b9b50@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
2026-07-15 16:00:52 -07:00
Alexandre Courbot 686a7fd1f7 gpu: nova-core: gsp: sequencer: do not store sequence into GspSequencer
The sequence is currently stored in the `GspSequencer` even though its
lifetime is limited to `GspSequencer::run`. This object-oriented design
does not play well with the borrow-checker, as `GspSequencer::iter`
borrows the `GspSequencer`, which makes it difficult to introduce
mutable references in `GspBootContext`, as we want to do in order to
make the `Falcon` references mutable.

Thus, store the sequence locally in `GspSequencer::run`, and move
iterator creation to `GspSeqIter::new` so it no longer needs to borrow
the whole `GspSequencer`.

Reviewed-by: Eliot Courtney <ecourtney@nvidia.com>
Link: https://patch.msgid.link/20260709-nova-bootcontext-v6-2-520cbf8b9b50@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
2026-07-15 16:00:52 -07:00
Alexandre Courbot d3cac8a343 gpu: nova-core: gsp: sequencer: use GspBootContext
`GspBootContext` contains all the resources currently carried by
`GspSequencerParams`, so replace the latter with the former for better
integration with the boot process and less code.

Reviewed-by: Eliot Courtney <ecourtney@nvidia.com>
Link: https://patch.msgid.link/20260709-nova-bootcontext-v6-1-520cbf8b9b50@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
2026-07-15 16:00:52 -07:00
Danilo Krummrich 2059254536 Merge tag 'rust-io-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core into drm-rust-next
I/O type generalization and projection

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

This is a stable tag for other trees to merge.

Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-14 00:01:38 +02:00
Younes Akhouayri 6cb3fdc9f5 rust: drm: Fix typo in FEAT_RENDER documentation
Correct the spelling of "privilege" in the DRIVER_RENDER Rustdoc.

Signed-off-by: Younes Akhouayri <git@younes.io>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260712-docs-drm-feat-render-rustdoc-typo-v1-1-c9df1cbbce4b@younes.io
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-13 18:13:26 +02:00
Sami Tolvanen 727dc02ec6 rust: drm: gpuvm: implement Send and Sync for GpuVaAlloc and GpuVmBo
Moving a GpuVaAlloc or GpuVmBo between threads currently forces drivers
to write their own unsafe Send and Sync impls. Provide the markers in
the abstraction instead.

GpuVaAlloc wraps only uninitialised memory and exposes none of it.
GpuVmBo hands out the driver data and GEM object by shared reference and
drops them in its deferred put; the DriverGpuVm trait already guarantees
both are Send + Sync, so both impls are unconditional.

Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Link: https://patch.msgid.link/20260611-gpuvm-sync-send-v4-2-6c7f4ab2778a@google.com
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
2026-07-13 15:43:07 +00:00
Sami Tolvanen b59ec72fec rust: drm: gpuvm: require Send + Sync for the driver's associated data
DriverGpuVm permitted !Send/!Sync associated data on an abstraction whose
handles are shared and dropped across threads: obtain() runs from many
threads and the VA API performs deferred cross-thread drops. That is
unsound.

Require Send + Sync on the trait and its associated data so the GpuVm and
UniqueRefGpuVm handle impls need no per-impl bounds.

Fixes: 82b78182ea ("rust: drm: add base GPUVM immediate mode abstraction")
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Link: https://patch.msgid.link/20260611-gpuvm-sync-send-v4-1-6c7f4ab2778a@google.com
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
2026-07-13 15:43:07 +00:00
Yilin Chen 9a80ddbf66 rust: drm: fix GEM object pointer safety docs
IntoGEMObject::from_raw() receives a pointer to struct drm_gem_object,
not a pointer to Self. The previous documentation used Self even though
the function argument is the embedded GEM object pointer.

However, the pointer must not be any arbitrary valid drm_gem_object. The
implementations recover Self with container_of(), so the GEM object must
be embedded in a valid Self instance. This patch documents that requirement
explicitly.

Assisted-by: Codex:GPT-5
Signed-off-by: Yilin Chen <1479826151@qq.com>
Link: https://patch.msgid.link/tencent_4426892E62B77DEA2AE898E899A871940005@qq.com
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
2026-07-13 08:18:37 +00:00
Danilo Krummrich aea0aeeff1 Merge patch series "rust: drm: Higher-Ranked Lifetime private data"
Danilo Krummrich <dakr@kernel.org> says:

DRM ioctls run in process context without any guarantee that the parent
bus device is still bound. This series solves the problem by introducing
RegistrationGuard -- a guard representing a drm_dev_enter/exit SRCU
critical section that proves the parent bus device is bound for the
lifetime of the guard.

As initial plumbing for this, the DRM DeviceContext typestates are
reworked: Uninit is renamed to Normal, defaults are adjusted,
AlwaysRefCounted is restricted to Normal, and a Deref chain from
Device<T, Registered> to Device<T, Normal> is established. This gives
Device<T, Registered> the semantic that the device is currently
registered and the parent bus device is bound, which makes the
RegistrationGuard and ioctl dispatch much cleaner. An Ioctl context
restricts registration_guard() to ioctl dispatch, where the DRM core
guarantees prior registration.

On top of that, add RegistrationData as a GAT (Generic Associated Type)
on drm::Driver, allowing drivers to store data whose lifetime is tied to
the parent bus device binding scope. The data is allocated in
Registration::new(), lifetime-erased to 'static for storage, and made
accessible through Device<T, Registered>::registration_data_with(). The
closure's HRTB ties the lifetime to the closure scope; internally the
'static pointer is cast back to the closure-scoped lifetime. The
reference is valid for the duration of the drm_dev_enter/exit critical
section held by RegistrationGuard.

Also update the ioctl dispatch macro to wrap every handler in a
RegistrationGuard, returning ENODEV if the device has been unplugged,
and pass the registration data to handlers.

Link: https://patch.msgid.link/20260628145406.2107056-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 16:59:55 +02:00
Danilo Krummrich 354a8f8b09 drm: nova: Use drm::Device<Registered> to access the parent bus device
The get_param ioctl needs access to the parent auxiliary device. Since
ioctl handlers run inside a RegistrationGuard, accept
&NovaDevice<Registered> to obtain &auxiliary::Device<Bound> via as_ref()
directly. This removes the need for drm::Device data, hence set it to
().

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-20-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 16:06:43 +02:00
Danilo Krummrich 3ba210061c rust: drm: Pass registration data to ioctl handlers
Pass registration data to ioctl handlers via
drm::Device<Registered>::registration_data_with(). The closure's HRTB
ties the lifetime to the closure scope, and the pointer cast shortens it
from 'static internally. The reference is valid for the duration of the
drm_dev_enter/exit critical section held by RegistrationGuard.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-19-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 16:06:43 +02:00
Danilo Krummrich e15b88223d rust: drm: Add RegistrationData to drm::Driver
Add a RegistrationData GAT (Generic Associated Type) to drm::Driver.
The lifetime parameter is tied to the parent bus device binding scope.
Registration<'a, T> takes ownership of the data via Pin<KBox<_>>,
storing it with its real lifetime. The pointer is written to drm::Device
before drm_dev_register() to ensure it is already in place when ioctls
arrive.

Device<T, Registered>::registration_data_with() provides access with the
lifetime shortened from 'static via a pointer cast. Since
Registration::drop() calls drm_dev_unplug(), which performs an SRCU
barrier waiting for all drm_dev_enter() critical sections to complete,
the data is guaranteed to remain valid for the duration of any
RegistrationGuard.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-18-dakr@kernel.org
[ Move registration_data_unchecked() to Device<T, Registered> impl
  block. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 16:05:44 +02:00
Danilo Krummrich eb197f7d60 drm: fix race between partial drm_dev_register() failure and ioctl
If drm_dev_register() fails after registering a minor (e.g. render minor
registered, primary minor fails), userspace could have opened the first
minor and entered a drm_dev_enter() critical section. Since the
unplugged flag was never set, the ioctl proceeds while the error path
tears down device resources.

Fix this by introducing drm_dev_synchronize_unplug(), which sets the
unplugged flag and waits for the SRCU barrier, ensuring all in-flight
drm_dev_enter() critical sections complete before cleanup proceeds; call
it on the error path of drm_dev_register().

Fixes: bee330f3d6 ("drm: Use srcu to protect drm_device.unplugged")
Cc: stable@vger.kernel.org
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/all/20260620190648.2E9F61F000E9@smtp.kernel.org/
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-17-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 16:01:07 +02:00
Danilo Krummrich 453197b7cc rust: drm: add AsRef<ParentDevice<Bound>> for Device<Registered>
Implement AsRef<T::ParentDevice<Bound>> for Device<T, Registered>,
providing access to the bound parent bus device for registered DRM
devices.

Since a Device<T, Registered> guarantees that the parent bus device is
bound, the conversion to T::ParentDevice<Bound> is safe.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-16-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 16:01:06 +02:00
Danilo Krummrich 47f600d40b rust: drm: return ParentDevice from Device AsRef
Change AsRef for drm::Device to return &T::ParentDevice<device::Normal>
instead of &device::Device, and restrict it to the Normal context.
Device<T, Registered> still gets this through Deref coercion.

This provides access to the typed parent bus device rather than the raw
base device.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-15-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 16:01:06 +02:00
Danilo Krummrich 478da53e5b rust: drm: Wrap ioctl dispatch in RegistrationGuard
Make Ioctl handlers receive a &Device<T, Registered> reference, proving
at the type level that the device is registered and its parent bus
device is bound.

This is achieved by calling registration_guard() on the Device<T, Ioctl>
obtained in ioctl dispatch context. If the device has been unplugged,
the ioctl returns -ENODEV without calling the handler.

To resolve the driver type parameter T for type inference, which the
compiler cannot propagate through method resolution and associated-type
projections alone, a dead-code closure and a helper function are used as
a type-inference anchor.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-14-dakr@kernel.org
[ Use imperative mood in commit message; clarify __dev_ctx_cast() doc
  comment to reflect Ioctl-to-Registered cast. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 15:59:28 +02:00
Danilo Krummrich 2455d5f2d5 rust: drm: Add RegistrationGuard for drm_dev_enter/exit critical sections
DRM ioctls do not guarantee that the parent bus device is still bound.
However, since DRM device registration is managed through Devres, using
drm_dev_unplug() on unregistration ensures that between drm_dev_enter()
and drm_dev_exit() the parent device must be bound.

Add RegistrationGuard, a guard object representing a drm_dev_enter/exit
SRCU critical section that dereferences to &Device<T, Registered>. The
guard is obtained from Device<T, Ioctl> and proves at runtime that the
device is still registered.

Switch Registration::drop from drm_dev_unregister() to drm_dev_unplug()
to provide the SRCU barrier that RegistrationGuard's safety argument
relies on.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-13-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 15:56:52 +02:00
Danilo Krummrich 86b20b1150 rust: drm: add Ioctl device context typestate
Add the Ioctl DeviceContext for DRM devices that have been registered
with userspace previously.

A Device<T, Ioctl> has been registered at some point, but may be
concurrently unregistering or already unregistered. drm_dev_enter() can
guard against this, ensuring the device remains registered for the
duration of the critical section.

This typestate will be used in ioctl dispatch context where registration
is guaranteed by the DRM core, and RegistrationGuard can safely be
acquired.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-12-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 15:56:52 +02:00
Danilo Krummrich 499eb35cd4 rust: drm: pin ioctl Device reference to Normal context
Explicitly annotate the Device reference produced by from_raw() in the
ioctl dispatch macro as Device<_, Normal>. Without this annotation, the
context is inferred from the handler's first parameter type, which would
allow a handler declaring &Device<T, Registered> to obtain a Registered
reference without runtime proof via RegistrationGuard.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-11-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 15:56:52 +02:00
Danilo Krummrich 1c8a1f88ac rust: drm: split Deref for Device context typestates
Split the Deref implementation for drm::Device by context:

  - Device<T> (Normal) dereferences to T::Data.
  - Device<T, Registered> dereferences to Device<T> (Normal).

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-10-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 15:56:52 +02:00
Danilo Krummrich 7f994b8912 rust: drm/gem: remove DeviceContext from shmem::Object
Now that AlwaysRefCounted is restricted to the Normal GEM Object
context, there is no use for instantiating Object<T, C> with a
non-Normal context. Remove the DeviceContext generic parameter from
shmem::Object and all associated types (VMap, VMapRef, VMapOwned,
DmaResvGuard, SGTableMap), simplifying the API.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-9-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 15:56:52 +02:00
Danilo Krummrich ec8b2cc27c rust: drm: restrict AlwaysRefCounted to Normal GEM Object context
Restrict AlwaysRefCounted for gem::Object and gem::shmem::Object to the
Normal context, since only Normal objects should be independently
reference-counted.

To avoid cascading through IntoGEMObject (which had AlwaysRefCounted as
a supertrait), remove AlwaysRefCounted from IntoGEMObject's supertraits
and instead add it as an explicit bound on lookup_handle(), which is the
only BaseObject method that returns an ARef.

Since Object::new() and shmem::Object::new() return ARef<Self>, move
them to Normal-only impl blocks. Similarly, simplify ObjectConfig and
shmem's parent_resv_obj field to the Normal context.

Remove the DeviceContext generic from DriverObject::new() and
Driver::Object, since GEM objects can only be constructed in the Normal
context. Simplify DriverAllocImpl accordingly.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-8-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 15:56:52 +02:00
Danilo Krummrich 506a7d63da rust: drm: restrict AlwaysRefCounted to Normal Device context
Restrict the AlwaysRefCounted implementation for drm::Device to the
Normal context. Registered devices represent a non-owning view of a
device within a RegistrationGuard scope and must not be independently
reference-counted.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-7-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 15:56:52 +02:00
Danilo Krummrich 9030013008 rust: drm: change default DeviceContext to Normal
Change the default DeviceContext from Registered to Normal for
drm::Device, gem::Object, gem::shmem::Object and
gem::shmem::ObjectConfig.

Normal is the general-purpose, reference-counted context suitable for
most uses; Registered represents a device that was registered with
userspace and will become a non-owning context obtained through a
RegistrationGuard.

Update the create_handle/lookup_handle bounds from Object<Registered> to
Object<Normal> to match the new default context of GEM objects, and
update the driver device type aliases (NovaDevice, TyrDrmDevice) to
default to Normal.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-6-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 15:56:52 +02:00
Danilo Krummrich 49e27d58a0 rust: drm: Add Driver::ParentDevice associated type
Add a ParentDevice associated type to the Driver trait, allowing each
DRM driver to declare its parent bus device type (e.g.
auxiliary::Device, platform::Device).

Change UnregisteredDevice::new() to take &T::ParentDevice<Bound>,
ensuring at the type level that the DRM device's parent matches the
declared bus device type.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-5-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 15:56:52 +02:00
Danilo Krummrich 893f39dada rust: faux: add Device type with AsBusDevice support
Add a faux::Device type that wraps struct faux_device and implements
AsBusDevice, enabling faux devices to be used as parent devices for
subsystems that require a bus device, such as DRM.

Update Registration to return &faux::Device<Bound> via AsRef.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-4-dakr@kernel.org
[ Drop redundant 'struct device' invariant; implied by valid
  struct faux_device. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 15:55:51 +02:00
Danilo Krummrich fd0f827c53 rust: drm: rename Uninit DeviceContext to Normal
Rename the Uninit DeviceContext to Normal to better reflect its purpose
as the general-purpose, reference-counted device context. The Uninit
name was a leftover from when DRM device private data initialization was
planned to split across UnregisteredDevice::new() and
Registration::new(); with the subsequent introduction of
RegistrationData, this distinction is no longer needed.

This also simplifies the DeviceContext documentation, trimming the
multi-stage initialization description that no longer applies.
Subsequent patches will refine the semantics of the Registered context
accordingly.

No functional change.

Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-3-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 15:35:11 +02:00
Danilo Krummrich 68b151bc61 rust: drm: ioctl: fix unbounded lifetimes in ioctl handler arguments
References to dev, data, and file in the declare_drm_ioctls! macro are
created via unsafe pointer dereferences, producing unbounded lifetimes.
If an ioctl handler explicitly annotates its parameters with 'static,
the compiler accepts this, allowing the handler to stash references that
outlive the ioctl call.

Fix this by adding a higher-ranked function pointer coercion that
enforces the handler accepts universally quantified lifetimes:

  let _: for<'a> fn(&'a _, &'a mut _, &'a _) -> _ = $func;

Since the handler must be coercible to a function pointer accepting any
lifetime 'a, it can no longer demand 'static on any parameter.

Cc: stable@vger.kernel.org
Fixes: 9a69570682 ("rust: drm: ioctl: Add DRM ioctl abstraction")
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/all/20260620011346.A47D01F000E9@smtp.kernel.org/
Suggested-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Link: https://patch.msgid.link/20260628145406.2107056-2-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-12 15:34:37 +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 0722567f50 gpu: nova-core: use I/O projection for cleaner encapsulation
Use `io_project!` for PTE array and message queues to restore the proper
encapsulation.

The remaining `dma_read!` and `dma_write!` is now only acting on
primitives; thus replace by `io_read!` and `io_write!`.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260706-io_projection-v6-17-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
Gary Guo 9b36c13cbd rust: io: move Io methods to extension trait
`Io` trait now has a single required method with many more provided
methods. Provided methods may want to rely on their implementations to not
be arbitrarily overridden by implementers for correctness or soundness.
A good example is the `size` method, it may be relied by unsafe code and
thus must be consistent with the metadata obtained from `as_ptr`.

Thus, create a new trait to host `size` method, extract existing provided
methods to the new trait, and provide a blanket implementation. This
pattern is used extensively in userspace Rust libraries e.g. `tokio` where
`AsyncRead` has minimum methods and `AsyncReadExt` is what users mostly
interact with.

To avoid changing all user imports, the base trait is renamed to `IoBase`
and the newly added trait takes the existing `Io` name.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Suggested-by: Danilo Krummrich <dakr@kernel.org>
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-12-72cd5d055d54@garyguo.net
[ Add comment explaining the purpose of the Io blanket implementation.
  - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 18:07:41 +02:00
Gary Guo bed01ca9e9 rust: io: remove MmioOwned
`Io` trait is now very easy to implement. Thus, implement it on `Bar` and
`IoMem` directly and remove the `MmioOwned` struct.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
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-11-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 18:00:12 +02:00
Gary Guo 0adc93b853 pwm: th1520: remove unnecessary deref
`Deref` is automatic and should normally not be used directly.
Also, `IoMem` is going to be implementing `Io` directly, so it will no
longer to be implementing `Deref`.

Reported-by: Andreas Hindborg <a.hindborg@kernel.org>
Link: https://rust-for-linux.zulipchat.com/#narrow/channel/291565-Help/topic/.E2.9C.94.20Projection.20in.20dma.20bus.20address.20space/near/606672061
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-10-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 18:00:12 +02:00
Gary Guo e0454ec122 rust: io: use view types instead of addresses for Io
Currently, `io_read` and `io_write` methods require the exact type of `Io`
plus an address. This means that they need to be monomorphized for each
different `Io` instance. This also means that multiple I/O implementors for
the same I/O kind needs to duplicate implementation (e.g. `Mmio` and
`MmioOwned`).

Create a new `IoBackend` trait and define these operations on it instead.
The operations are just going to receive a view type and operate on them.
This has the additional advantage that the invariants can be moved from the
trait (and guaranteed via `unsafe`) to type invariants on the canonical
view types of the backends, so `io_read` and `io_write` can be safe.

Note that a view type is needed; addresses are insufficient in this
design, as they do not carry sufficient information. For example,
`ConfigSpace` needs `&pci::Device` in addition to the address.

`io_addr_assert` and `io_addr` are renamed to `io_view*` to reflect
that they operate on views now, and make them standalone functions so
they cannot be used by users to cast types outside io.rs.

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-9-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 17:59:32 +02:00
Gary Guo 6e5f28968d rust: pci: io: make ConfigSpace a view
In order to support I/O projection, we are splitting I/O types into two
categories: owned objects and views. Owned objects have a specific type
that is related to setting up and tearing down, while views can have their
type changed with I/O projection.

Things like `IoMem` or `Bar` are owned objects, which requires setting up
mapping and cleaning up on drop. On the other side, `ConfigSpace` is really
just a view, as the resource is associated with the `pci::Device`.

Remove the `ConfigSpaceKind` bound on `ConfigSpace` and make it a generic
view. This means that `ConfigSpace` object now represents a subregion and
therefore encodes offset (as address of pointers) and size (as metadata of
pointers) itself. The full region case is still supported with offset 0 and
size of `cfg_size`.

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-8-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 17:59:32 +02:00
Gary Guo 9f64c84af0 rust: io: implement Mmio as view type
Implement `Mmio` as view type and convert `RelaxedMmio` to view type as
well. I/O implementations of `MmioOwned` are changed to delegate to the
`Mmio` view type.

All existing users of `MmioOwned` in the documentation which do not
actually reflect the owning semantics is converted.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Tested-by: Daniel Almeida <daniel.almeida@collabora.com>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Link: https://patch.msgid.link/20260706-io_projection-v6-7-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 17:59:32 +02:00
Gary Guo 691c75967d rust: io: rename Mmio to MmioOwned
Most users would more commonly reach out to a view of `Mmio` rather than an
owned instance of `Mmio`. Only implementor of `Io` like `Bar` or `IoMem`
would need the owned version. Thus, rename `Mmio` to `MmioOwned` so that
the name `Mmio` can be used for the view type instead.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
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-6-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 17:59:32 +02:00
Gary Guo 9734e90511 rust: io: generalize MmioRaw to pointer to arbitrary type
Conceptually, `MmioRaw` is just `__iomem *`, so it should work for any
types. Update the existing use case where it represents a region of
compile-time known minimum size and run-time known actual size to use the
dynamic-sized type `Region<SIZE>` instead. Rename `maxsize` method to
reflect that it is the actual size (not a bound) of the region.

Implement `Clone` and `Copy` manually, which cannot be derived due to the
generic parameter. The use of raw pointers also cause the `Send` and `Sync`
auto trait implementation to be lost, so add them back by manual
implementation.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
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-5-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 17:59:32 +02:00
Gary Guo 46b1b54139 rust: io: implement Io on reference types instead
Currently, `Io` is implemented on owned I/O objects (e.g. `Bar`). This is
going to change with I/O projections, as then `Io` needs to work both for
owned objects and views of them. Views are themselves reference-like
(however they obviously cannot be references, because they belong to a
different address space).

To facilitate the change, change `Io` to be implemented on reference types
for the owned I/O objects, and make methods take `self` instead of `&self`.
When I/O views are implemented, we can then naturally implement `Io` for
these objects.

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-4-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11 17:59:32 +02:00