From: Danilo Krummrich <dakr@kernel.org>
To: airlied@gmail.com, simona@ffwll.ch,
maarten.lankhorst@linux.intel.com, mripard@kernel.org,
tzimmermann@suse.de, lyude@redhat.com, lina@asahilina.net,
daniel.almeida@collabora.com, j@jannau.net, alyssa@rosenzweig.io
Cc: ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com,
gary@garyguo.net, bjorn3_gh@protonmail.com,
benno.lossin@proton.me, a.hindborg@kernel.org,
aliceryhl@google.com, tmgross@umich.edu,
dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org,
Danilo Krummrich <dakr@kernel.org>
Subject: [PATCH v2 5/8] rust: drm: add DRM driver registration
Date: Fri, 11 Apr 2025 01:55:24 +0200 [thread overview]
Message-ID: <20250410235546.43736-6-dakr@kernel.org> (raw)
In-Reply-To: <20250410235546.43736-1-dakr@kernel.org>
From: Asahi Lina <lina@asahilina.net>
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>
[ 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>
---
rust/kernel/drm/driver.rs | 60 ++++++++++++++++++++++++++++++++++++++-
rust/kernel/drm/mod.rs | 1 +
2 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/drm/driver.rs b/rust/kernel/drm/driver.rs
index 6d09d1933d3e..96bb287eada2 100644
--- a/rust/kernel/drm/driver.rs
+++ b/rust/kernel/drm/driver.rs
@@ -4,7 +4,15 @@
//!
//! C header: [`include/linux/drm/drm_drv.h`](srctree/include/linux/drm/drm_drv.h)
-use crate::{bindings, drm, str::CStr};
+use crate::{
+ bindings, device,
+ devres::Devres,
+ drm,
+ error::{Error, Result},
+ prelude::*,
+ str::CStr,
+ types::ARef,
+};
use macros::vtable;
/// Driver use the GEM memory manager. This should be set for all modern drivers.
@@ -107,3 +115,53 @@ pub trait Driver {
/// IOCTL list. See `kernel::drm::ioctl::declare_drm_ioctls!{}`.
const IOCTLS: &'static [drm::ioctl::DrmIoctlDescriptor];
}
+
+/// The registration type of a `drm::Device`.
+///
+/// Once the `Registration` structure is dropped, the device is unregistered.
+pub struct Registration<T: Driver>(ARef<drm::Device<T>>);
+
+impl<T: Driver> Registration<T> {
+ /// Creates a new [`Registration`] and registers it.
+ pub fn new(drm: &drm::Device<T>, flags: usize) -> Result<Self> {
+ // SAFETY: Safe by the invariants of `drm::Device`.
+ let ret = unsafe { bindings::drm_dev_register(drm.as_raw(), flags) };
+ if ret < 0 {
+ return Err(Error::from_errno(ret));
+ }
+
+ Ok(Self(drm.into()))
+ }
+
+ /// Same as [`Registration::new`}, but transfers ownership of the [`Registration`] to
+ /// [`Devres`].
+ pub fn new_foreign_owned(drm: &drm::Device<T>, dev: &device::Device, flags: usize) -> Result {
+ if drm.as_ref().as_raw() != dev.as_raw() {
+ return Err(EINVAL);
+ }
+
+ let reg = Registration::<T>::new(drm, flags)?;
+ Devres::new_foreign_owned(dev, reg, GFP_KERNEL)
+ }
+
+ /// Returns a reference to the `Device` instance for this registration.
+ pub fn device(&self) -> &drm::Device<T> {
+ &self.0
+ }
+}
+
+// SAFETY: `Registration` doesn't offer any methods or access to fields when shared between
+// threads, hence it's safe to share it.
+unsafe impl<T: Driver> Sync for Registration<T> {}
+
+// SAFETY: Registration with and unregistration from the DRM subsystem can happen from any thread.
+unsafe impl<T: Driver> Send for Registration<T> {}
+
+impl<T: Driver> Drop for Registration<T> {
+ /// Removes the registration from the kernel if it has completed successfully before.
+ fn drop(&mut self) {
+ // SAFETY: Safe by the invariant of `ARef<drm::Device<T>>`. The existence of this
+ // `Registration` also guarantees the this `drm::Device` is actually registered.
+ unsafe { bindings::drm_dev_unregister(self.0.as_raw()) };
+ }
+}
diff --git a/rust/kernel/drm/mod.rs b/rust/kernel/drm/mod.rs
index 967854a2083e..2d88e70ba607 100644
--- a/rust/kernel/drm/mod.rs
+++ b/rust/kernel/drm/mod.rs
@@ -9,6 +9,7 @@
pub use self::device::Device;
pub use self::driver::Driver;
pub use self::driver::DriverInfo;
+pub use self::driver::Registration;
pub(crate) mod private {
pub trait Sealed {}
--
2.49.0
next prev parent reply other threads:[~2025-04-10 23:56 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-10 23:55 [PATCH v2 0/8] DRM Rust abstractions Danilo Krummrich
2025-04-10 23:55 ` [PATCH v2 1/8] drm: drv: implement __drm_dev_alloc() Danilo Krummrich
2025-04-14 13:27 ` Alyssa Rosenzweig
2025-04-18 21:00 ` Lyude Paul
2025-04-10 23:55 ` [PATCH v2 2/8] rust: drm: ioctl: Add DRM ioctl abstraction Danilo Krummrich
2025-04-14 13:54 ` Alyssa Rosenzweig
2025-04-18 21:03 ` Lyude Paul
2025-04-10 23:55 ` [PATCH v2 3/8] rust: drm: add driver abstractions Danilo Krummrich
2025-04-14 14:00 ` Alyssa Rosenzweig
2025-04-18 21:06 ` Lyude Paul
2025-04-10 23:55 ` [PATCH v2 4/8] rust: drm: add device abstraction Danilo Krummrich
2025-04-14 14:07 ` Alyssa Rosenzweig
2025-04-17 18:53 ` Lyude Paul
2025-04-17 20:20 ` Danilo Krummrich
2025-04-10 23:55 ` Danilo Krummrich [this message]
2025-04-14 14:11 ` [PATCH v2 5/8] rust: drm: add DRM driver registration Alyssa Rosenzweig
2025-04-18 21:12 ` Lyude Paul
2025-04-10 23:55 ` [PATCH v2 6/8] rust: drm: file: Add File abstraction Danilo Krummrich
2025-04-14 14:28 ` Alyssa Rosenzweig
2025-04-18 21:15 ` Lyude Paul
2025-04-10 23:55 ` [PATCH v2 7/8] rust: drm: gem: Add GEM object abstraction Danilo Krummrich
2025-04-14 15:07 ` Alyssa Rosenzweig
2025-04-17 18:42 ` Lyude Paul
2025-04-17 20:31 ` Danilo Krummrich
2025-04-17 22:33 ` Lyude Paul
2025-04-18 5:31 ` Danilo Krummrich
2025-05-12 11:41 ` Miguel Ojeda
2025-05-12 11:48 ` Miguel Ojeda
2025-05-12 12:09 ` Danilo Krummrich
2025-05-12 12:38 ` Miguel Ojeda
2025-04-10 23:55 ` [PATCH v2 8/8] MAINTAINERS: add DRM Rust source files to DRM DRIVERS Danilo Krummrich
2025-04-14 15:08 ` Alyssa Rosenzweig
2025-04-18 21:16 ` [PATCH v2 0/8] DRM Rust abstractions Lyude Paul
2025-04-24 13:59 ` Danilo Krummrich
-- strict thread matches above, loose matches on Subject: below --
2024-06-18 23:31 [PATCH v2 0/8] DRM Rust abstractions and Nova Danilo Krummrich
2024-06-18 23:31 ` [PATCH v2 5/8] rust: drm: add DRM driver registration Danilo Krummrich
2024-07-02 17:26 ` Lyude Paul
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250410235546.43736-6-dakr@kernel.org \
--to=dakr@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=airlied@gmail.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=alyssa@rosenzweig.io \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=daniel.almeida@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=gary@garyguo.net \
--cc=j@jannau.net \
--cc=lina@asahilina.net \
--cc=lyude@redhat.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
--cc=tmgross@umich.edu \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.