There's a few issues with this function, mainly:
* This function -probably- should have been unsafe from the start. Pointers
are not always necessarily valid, but you want a function that does
field-projection for a pointer that can travel outside of the original
struct to be unsafe, at least if I understand properly.
* *mut Self is not terribly useful in this context, the majority of uses of
from_gem_obj() grab a *mut Self and then immediately convert it into a
&'a Self. It also goes against the ffi conventions we've set in the rest
of the kernel thus far.
* from_gem_obj() also doesn't follow the naming conventions in the rest of
the DRM bindings at the moment, as_ref() would be a better name.
So, let's:
* Make from_gem_obj() unsafe
* Convert it to return &'a Self
* Rename it to as_ref()
* Update all call locations
Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Link: https://lore.kernel.org/r/20250513221046.903358-3-lyude@redhat.com
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
The layout of NV_PMC_BOOT_0 has two small issues:
- The "chipset" field, while useful to identify a chip, is actually an
aggregate of two distinct fields named "architecture" and
"implementation".
- The "architecture" field is split, with its MSB being at a different
location than the rest of its bits.
Redefine the register layout to match its actual definition as provided
by OpenRM and expose the fully-constructed "architecture" field through
our own "Architecture" type. The "chipset" pseudo-field is also useful
to have, so keep providing it.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://lore.kernel.org/r/20250507-nova-frts-v3-6-fcb02749754d@nvidia.com
[ Use Result from kernel::prelude. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Add the register!() macro, which defines a given register's layout and
provide bit-field accessors with a way to convert them to a given type.
This macro will allow us to make clear definitions of the registers and
manipulate their fields safely.
The long-term goal is to eventually move it to the kernel crate so it
can be used by other drivers as well, but it was agreed to first land it
into nova-core and make it mature there.
To illustrate its usage, use it to define the layout for the Boot0
(renamed to NV_PMC_BOOT_0 to match OpenRM's naming scheme) and take
advantage of its accessors.
Suggested-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://lore.kernel.org/r/20250507-nova-frts-v3-5-fcb02749754d@nvidia.com
[ Fix typo in commit message. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
We will need to perform things like allocating DMA memory during device
creation, so make sure to take the device context that will allow us to
perform these actions. This also allows us to use Devres::access to
obtain the BAR without holding a RCU lock.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://lore.kernel.org/r/20250507-nova-frts-v3-4-fcb02749754d@nvidia.com
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Add the initial nova-drm driver skeleton.
nova-drm is connected to nova-core through the auxiliary bus and
implements the DRM parts of the nova driver stack.
For now, it implements the fundamental DRM abstractions, i.e. creates a
DRM device and registers it, exposing a three sample IOCTLs.
DRM_IOCTL_NOVA_GETPARAM
- provides the PCI bar size from the bar that maps the GPUs VRAM
from nova-core
DRM_IOCTL_NOVA_GEM_CREATE
- creates a new dummy DRM GEM object and returns a handle
DRM_IOCTL_NOVA_GEM_INFO
- provides metadata for the DRM GEM object behind a given handle
I implemented a small userspace test suite [1] that utilizes this
interface.
Link: https://gitlab.freedesktop.org/dakr/drm-test [1]
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Acked-by: Dave Airlie <airlied@redhat.com>
Link: https://lore.kernel.org/r/20250424160452.8070-3-dakr@kernel.org
[ Kconfig: depend on DRM=y rather than just DRM. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
The doctest requires `CONFIG_PCI`:
error[E0432]: unresolved import `kernel::pci`
--> rust/doctests_kernel_generated.rs:2689:44
|
2689 | use kernel::{device::Core, devres::Devres, pci};
| ^^^ no `pci` in the root
|
note: found an item that was configured out
--> rust/kernel/lib.rs:96:9
note: the item is gated here
--> rust/kernel/lib.rs:95:1
Thus conditionally compile it (which still checks the syntax).
Fixes: f301cb978c ("rust: devres: implement Devres::access()")
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/r/20250511182533.1016163-1-ojeda@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Implement a direct accessor for the data stored within the Devres for
cases where we can prove that we own a reference to a Device<Bound>
(i.e. a bound device) of the same device that was used to create the
corresponding Devres container.
Usually, when accessing the data stored within a Devres container, it is
not clear whether the data has been revoked already due to the device
being unbound and, hence, we have to try whether the access is possible
and subsequently keep holding the RCU read lock for the duration of the
access.
However, when we can prove that we hold a reference to Device<Bound>
matching the device the Devres container has been created with, we can
guarantee that the device is not unbound for the duration of the
lifetime of the Device<Bound> reference and, hence, it is not possible
for the data within the Devres container to be revoked.
Therefore, in this case, we can bypass the atomic check and the RCU read
lock, which is a great optimization and simplification for drivers.
Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Acked-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
Link: https://lore.kernel.org/r/20250428140137.468709-3-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
When `CONFIG_AUXILIARY_BUS` is disabled, `parent()` is still dead code:
error: method `parent` is never used
--> rust/kernel/device.rs:71:19
|
64 | impl<Ctx: DeviceContext> Device<Ctx> {
| ------------------------------------ method in this implementation
...
71 | pub(crate) fn parent(&self) -> Option<&Self> {
| ^^^^^^
|
= note: `-D dead-code` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(dead_code)]`
Thus reintroduce the `expect`, but now as a conditional one. Do so as
`dead_code` since that is narrower.
An `allow` would also be possible, but Danilo wants to catch new users
in the future [1].
Link: https://lore.kernel.org/rust-for-linux/aBE8qQrpXOfru_K3@pollux/ [1]
Fixes: ce735e73dd ("rust: auxiliary: add auxiliary device / driver abstractions")
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/r/20250429210629.513521-1-ojeda@kernel.org
[ Adjust commit subject to "rust: device: conditionally expect
`dead_code` for `parent()`". - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
DRM GEM is the DRM memory management subsystem used by most modern
drivers; add a Rust abstraction for DRM GEM.
This includes the BaseObject trait, which contains operations shared by
all GEM object classes.
Signed-off-by: Asahi Lina <lina@asahilina.net>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Link: https://lore.kernel.org/r/20250410235546.43736-8-dakr@kernel.org
[ Rework of GEM object abstractions
* switch to the Opaque<T> type
* fix (mutable) references to struct drm_gem_object (which in this
context is UB)
* drop all custom reference types in favor of AlwaysRefCounted
* bunch of minor changes and simplifications (e.g. IntoGEMObject
trait)
* write and fix safety and invariant comments
* remove necessity for and convert 'as' casts
* original source archive: https://archive.is/dD5SL
- Danilo ]
[ Fix missing CONFIG_DRM guards in rust/helpers/drm.c. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
A DRM File is the DRM counterpart to a kernel file structure,
representing an open DRM file descriptor.
Add a Rust abstraction to allow drivers to implement their own File types
that implement the DriverFile trait.
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Asahi Lina <lina@asahilina.net>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Link: https://lore.kernel.org/r/20250410235546.43736-7-dakr@kernel.org
[ Rework of drm::File
* switch to the Opaque<T> type
* fix (mutable) references to struct drm_file (which in this context
is UB)
* restructure and rename functions to align with common kernel
schemes
* write and fix safety and invariant comments
* remove necessity for and convert 'as' casts
* original source archive: https://archive.is/GH8oy
- Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Implement the DRM driver `Registration`.
The `Registration` structure is responsible to register and unregister a
DRM driver. It makes use of the `Devres` container in order to allow the
`Registration` to be owned by devres, such that it is automatically
dropped (and the DRM driver unregistered) once the parent device is
unbound.
Signed-off-by: Asahi Lina <lina@asahilina.net>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Link: https://lore.kernel.org/r/20250410235546.43736-6-dakr@kernel.org
[ Rework of drm::Registration
* move VTABLE to drm::Device to prevent use-after-free bugs; VTABLE
needs to be bound to the lifetime of drm::Device, not the
drm::Registration
* combine new() and register() to get rid of the registered boolean
* remove file_operations
* move struct drm_device creation to drm::Device
* introduce Devres
* original source archive: https://archive.is/Pl9ys
- Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Implement the DRM driver abstractions.
The `Driver` trait provides the interface to the actual driver to fill
in the driver specific data, such as the `DriverInfo`, driver features
and IOCTLs.
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Asahi Lina <lina@asahilina.net>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Link: https://lore.kernel.org/r/20250410235546.43736-4-dakr@kernel.org
[ MISC changes
* remove unnecessary DRM features; make remaining ones crate private
* add #[expect(unused)] to avoid warnings
* add sealed trait
* remove shmem::Object references
* original source archive: https://archive.is/Pl9ys
- Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
DRM drivers need to be able to declare which driver-specific ioctls they
support. Add an abstraction implementing the required types and a helper
macro to generate the ioctl definition inside the DRM driver.
Note that this macro is not usable until further bits of the abstraction
are in place (but it will not fail to compile on its own, if not called).
Signed-off-by: Asahi Lina <lina@asahilina.net>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Link: https://lore.kernel.org/r/20250410235546.43736-3-dakr@kernel.org
[ MISC fixes
* wrap raw_data in Opaque to avoid UB when creating a reference
* fix IOCTL sample declaration
* fix safety comment of IOCTL argument
* original source archive: https://archive.is/LqHDQ
- Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
In the Rust DRM device abstraction we need to allocate a struct
drm_device.
Currently, there are two options, the deprecated drm_dev_alloc() (which
does not support subclassing) and devm_drm_dev_alloc(). The latter
supports subclassing, but also manages the initial reference through
devres for the parent device.
In Rust we want to conform with the subclassing pattern, but do not want
to get the initial reference managed for us, since Rust has its own,
idiomatic ways to properly deal with it.
There are two options to achieve this.
1) Allocate the memory ourselves with a KBox.
2) Implement __drm_dev_alloc(), which supports subclassing, but is
unmanged.
While (1) would be possible, it would be cumbersome, since it would
require exporting drm_dev_init() and drmm_add_final_kfree().
Hence, go with option (2) and implement __drm_dev_alloc().
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Link: https://lore.kernel.org/r/20250410235546.43736-2-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Revocable::try_access() returns a guard through which the wrapped object
can be accessed. Code that can sleep is not allowed while the guard is
held; thus, it is common for the caller to explicitly drop it before
running sleepable code, e.g:
let b = bar.try_access()?;
let reg = b.readl(...);
// Don't forget this or things could go wrong!
drop(b);
something_that_might_sleep();
let b = bar.try_access()?;
let reg2 = b.readl(...);
This is arguably error-prone. try_access_with() provides an arguably
safer alternative, by taking a closure that is run while the guard is
held, and by dropping the guard automatically after the closure
completes. This way, code can be organized more clearly around the
critical sections and the risk of forgetting to release the guard when
needed is considerably reduced:
let reg = bar.try_access_with(|b| b.readl(...))?;
something_that_might_sleep();
let reg2 = bar.try_access_with(|b| b.readl(...))?;
The closure can return nothing, or any value including a Result which is
then wrapped inside the Option returned by try_access_with. Error
management is driver-specific, so users are encouraged to create their
own macros that map and flatten the returned values to something
appropriate for the code they are working on.
Suggested-by: Danilo Krummrich <dakr@kernel.org>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
Acked-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/r/20250411-try_with-v4-1-f470ac79e2e2@nvidia.com
[ Link `None`, `Some`, `Option` in doc-comment. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Add a sample Rust auxiliary driver based on a PCI driver for QEMU's
"pci-testdev" device.
The PCI driver only registers an auxiliary device, in order to make the
corresponding auxiliary driver probe.
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://lore.kernel.org/r/20250414131934.28418-6-dakr@kernel.org
[ Use `ok_or()` when accessing auxiliary::Device::parent(). - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Implement the basic auxiliary abstractions required to implement a
driver matching an auxiliary device.
The design and implementation is analogous to PCI and platform and is
based on the generic device / driver abstractions.
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20250414131934.28418-4-dakr@kernel.org
[ Fix typos, `let _ =` => `drop()`, use `kernel::ffi`. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Implement TryFrom<&device::Device> for &Device.
This allows us to get a &platform::Device from a generic &Device in a safe
way; the conversion fails if the device' bus type does not match with
the platform bus type.
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20250321214826.140946-4-dakr@kernel.org
[ Support device context types, use dev_is_platform() helper. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Implement TryFrom<&device::Device> for &Device.
This allows us to get a &pci::Device from a generic &Device in a safe
way; the conversion fails if the device' bus type does not match with
the PCI bus type.
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20250321214826.140946-3-dakr@kernel.org
[ Support device context types, use dev_is_pci() helper. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Introduce "Bound" device context
Introduce the "Bound" device context, such that it can be ensured to only
ever pass a bound device to APIs that require this precondition. [1]
This tag exists to share the patches from [1] between multiple trees.
[1] https://lore.kernel.org/lkml/20250413173758.12068-1-dakr@kernel.org/
The Bound device context indicates that a device is bound to a driver.
It must be used for APIs that require the device to be bound, such as
Devres or dma::CoherentAllocation.
Implement Bound and add the corresponding Deref hierarchy, as well as the
corresponding ARef conversion for this device context.
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20250413173758.12068-7-dakr@kernel.org
[ Add missing `::` prefix in macros. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Pull soundwire fix from Vinod Koul:
- add missing config symbol CONFIG_SND_HDA_EXT_CORE required for asoc
driver CONFIG_SND_SOF_SOF_HDA_SDW_BPT
* tag 'soundwire-6.15-rc1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire:
ASoC: SOF: Intel: Let SND_SOF_SOF_HDA_SDW_BPT select SND_HDA_EXT_CORE
Support up to 8192 processors
Add cpuidle governor debug telemetry, disabled by default
Update default output to exclude cpuidle invocation counts
Bug fixes
Signed-off-by: Len Brown <len.brown@intel.com>
Create "pct_idle" counter group, the sofware notion of residency
so it can now be singled out, independent of other counter groups.
Create "cpuidle" group, the cpuidle invocation counts.
Disable "cpuidle", by default.
Create "swidle" = "cpuidle" + "pct_idle".
Undocument "sysfs", the old name for "swidle", but keep it working
for backwards compatibilty.
Create "hwidle", all the HW idle counters
Modify "idle", enabled by default
"idle" = "hwidle" + "pct_idle" (and now excludes "cpuidle")
Signed-off-by: Len Brown <len.brown@intel.com>
Pull perf event fix from Ingo Molnar:
"Fix a perf events time accounting bug"
* tag 'perf-urgent-2025-04-06' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/core: Fix child_total_time_enabled accounting bug at task exit