From nobody Sat Feb 7 23:23:03 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B65FE21CC47; Mon, 20 Oct 2025 22:35:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999738; cv=none; b=fmgSdDw2TcxqDWzf/UKGijHfhr+36XMhEpfiXI+GzluIzEO2w2Xc4nXZMBKdn3cG48oots5IiXop3To8QslWOvJeyK+W/9b3PSnSuBZ4f8Olg3Uqt4f8LsFvW1J6TvA2rTGJeNx28nIGuzg6+PS8fVmeU8H0OQgB5heRExkyqUM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999738; c=relaxed/simple; bh=N4vezhO0wwYBBIpkBuSZJyupwVtIFp66xV6fNs6FXSo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uDOstgXrjlU24SxWS79dQ9JIBHqHpYpqA5VdShiGEpAfSCqouV0JyPX4l05QG8vH7gwipcEHqK9odnbpjAwWh3jPwFv3X9XPuA2gLQH0MsF4a7eLFlX7HZBLLVtc1wiNNM5k5K5GwZyfNPsRgCypBsQOIN3l7NGDsfnVaFEv1Ks= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cjFIomUR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cjFIomUR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12F86C113D0; Mon, 20 Oct 2025 22:35:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760999738; bh=N4vezhO0wwYBBIpkBuSZJyupwVtIFp66xV6fNs6FXSo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cjFIomURYwt3CumUaZ7D9MAOB3fygTEkOnuIw2MF9tcZ8FrwO5kJl5Q7g4Zau6mST Wjox5Gbws/mCRYEtllrwI8BzDoK7+He2h2XijmIGIbAikhw3NbsXNX+m6aotL/VUnD 8323srdc7Q1/R/T/hCEzPu1G3gYNLBL+v6uSze/cPtgb3EeTDL6nv0W1/83zCEEfWf o6kkKtBs5sWNsk95U1MwyXmXWRmtph/ubd98hxENnofPaWLUvxosbYiFEGc1RQbOQC COVTzDmYbNRuSbwINBXM4KPpYEnviDgk0+VmAR6kNm4AGnnQ237kuIm4WA+mHEN/SP H+FBykhcHGfzg== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, bhelgaas@google.com, kwilczynski@kernel.org, david.m.ertman@intel.com, ira.weiny@intel.com, leon@kernel.org, acourbot@nvidia.com, ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org, a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu, pcolberg@redhat.com Cc: rust-for-linux@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Danilo Krummrich Subject: [PATCH 1/8] rust: device: narrow the generic of drvdata_obtain() Date: Tue, 21 Oct 2025 00:34:23 +0200 Message-ID: <20251020223516.241050-2-dakr@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251020223516.241050-1-dakr@kernel.org> References: <20251020223516.241050-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Let T be the actual private driver data type without the surrounding box, as it leaves less room for potential bugs. Signed-off-by: Danilo Krummrich Reviewed-by: Alice Ryhl Reviewed-by: Greg Kroah-Hartman --- rust/kernel/auxiliary.rs | 2 +- rust/kernel/device.rs | 4 ++-- rust/kernel/pci.rs | 2 +- rust/kernel/platform.rs | 2 +- rust/kernel/usb.rs | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs index e12f78734606..a6a2b23befce 100644 --- a/rust/kernel/auxiliary.rs +++ b/rust/kernel/auxiliary.rs @@ -85,7 +85,7 @@ extern "C" fn remove_callback(adev: *mut bindings::auxili= ary_device) { // SAFETY: `remove_callback` is only ever called after a successfu= l call to // `probe_callback`, hence it's guaranteed that `Device::set_drvda= ta()` has been called // and stored a `Pin>`. - drop(unsafe { adev.as_ref().drvdata_obtain::>>() }); + drop(unsafe { adev.as_ref().drvdata_obtain::() }); } } =20 diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs index 343996027c89..106aa57a6385 100644 --- a/rust/kernel/device.rs +++ b/rust/kernel/device.rs @@ -215,7 +215,7 @@ pub fn set_drvdata(&self, data: impl PinIni= t) -> Result { /// - Must only be called once after a preceding call to [`Device::set= _drvdata`]. /// - The type `T` must match the type of the `ForeignOwnable` previou= sly stored by /// [`Device::set_drvdata`]. - pub unsafe fn drvdata_obtain(&self) -> T { + pub unsafe fn drvdata_obtain(&self) -> Pin> { // SAFETY: By the type invariants, `self.as_raw()` is a valid poin= ter to a `struct device`. let ptr =3D unsafe { bindings::dev_get_drvdata(self.as_raw()) }; =20 @@ -224,7 +224,7 @@ pub unsafe fn drvdata_obtain(&self) = -> T { // `into_foreign()`. // - `dev_get_drvdata()` guarantees to return the same pointer giv= en to `dev_set_drvdata()` // in `into_foreign()`. - unsafe { T::from_foreign(ptr.cast()) } + unsafe { Pin::>::from_foreign(ptr.cast()) } } =20 /// Borrow the driver's private data bound to this [`Device`]. diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs index 83e19bcec46e..e90b13aebac8 100644 --- a/rust/kernel/pci.rs +++ b/rust/kernel/pci.rs @@ -148,7 +148,7 @@ extern "C" fn remove_callback(pdev: *mut bindings::pci_= dev) { // SAFETY: `remove_callback` is only ever called after a successfu= l call to // `probe_callback`, hence it's guaranteed that `Device::set_drvda= ta()` has been called // and stored a `Pin>`. - let data =3D unsafe { pdev.as_ref().drvdata_obtain::>>= () }; + let data =3D unsafe { pdev.as_ref().drvdata_obtain::() }; =20 T::unbind(pdev, data.as_ref()); } diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs index 043721fdb6d8..8f7522c4cf89 100644 --- a/rust/kernel/platform.rs +++ b/rust/kernel/platform.rs @@ -91,7 +91,7 @@ extern "C" fn remove_callback(pdev: *mut bindings::platfo= rm_device) { // SAFETY: `remove_callback` is only ever called after a successfu= l call to // `probe_callback`, hence it's guaranteed that `Device::set_drvda= ta()` has been called // and stored a `Pin>`. - let data =3D unsafe { pdev.as_ref().drvdata_obtain::>>= () }; + let data =3D unsafe { pdev.as_ref().drvdata_obtain::() }; =20 T::unbind(pdev, data.as_ref()); } diff --git a/rust/kernel/usb.rs b/rust/kernel/usb.rs index 9238b96c2185..05eed3f4f73e 100644 --- a/rust/kernel/usb.rs +++ b/rust/kernel/usb.rs @@ -87,9 +87,9 @@ extern "C" fn disconnect_callback(intf: *mut bindings::us= b_interface) { // SAFETY: `disconnect_callback` is only ever called after a succe= ssful call to // `probe_callback`, hence it's guaranteed that `Device::set_drvda= ta()` has been called // and stored a `Pin>`. - let data =3D unsafe { dev.drvdata_obtain::>>() }; + let data =3D unsafe { dev.drvdata_obtain::() }; =20 - T::disconnect(intf, data.as_ref()); + T::disconnect(intf, data.data()); } } =20 --=20 2.51.0 From nobody Sat Feb 7 23:23:03 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 27A852F0C79; Mon, 20 Oct 2025 22:35:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999743; cv=none; b=oQoaNDw9bHZ9YWSeCisSz8pmn8NW6o/amq4hODhCWeKbqTEOF4Lwb9p3G44GAzKAOWxvOMAdhpmyet/dM3BE/PKj1hOhG4XFL6txF1mYirWFveRaat6usuNQN9IkghnWeN67Vz7iwmfmwsS5HE2FzNWY+L9lQ5XY389Oht/E6Tc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999743; c=relaxed/simple; bh=qL5kYGECCC85OsPH4HQK2aOGaWUZce7Vw+aqubE50Xo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Vznl0xL+8y6K8Ttx9BYbDIT75fVh9Ojc8XSUSnvbKCvgVY4/Ea1uGnoA+j0GTDs54/gWm0L3Qke4h6HuzXUVY5ro9xq9D85q142vyCFKRPEBKZQehLTG1gis90HY1SOPvga6TMy2ESlh3Rvl8EIoBnF0G6NrqbTPim1cO0coUPI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YJXT7WZL; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YJXT7WZL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B6FF0C4CEFB; Mon, 20 Oct 2025 22:35:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760999743; bh=qL5kYGECCC85OsPH4HQK2aOGaWUZce7Vw+aqubE50Xo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YJXT7WZLqSX3pJoQZatlOO8k357fgcmwT50/a9+0bpSwms5XS4r5Q/DODhkcWyw9j 2aMVPWmdph5X/WkyzB8MnJcIBX6uHBJ9mkRn1sEnO6EKLUOCsOmJLr59+hOslaFfhZ awAzqrJPVSd5u/YOjiLgFOQYi7zVUgYuH3Fe75j2X9MuXr37ZpMK9EbMEi5tOFPMzN eRNg71qoeswCCVxZiezMWVe1MhxtLH8AoEd2E06BqUCGC3XTOulnVxNTkuIqJwDRb4 RYLL141ypcXvsSLDWkNyM5fxWQPDGHkKWzr0XOVKiwRzSyHtxzv0r/EXjmnDtsUJWT +wWNc+isw4ziw== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, bhelgaas@google.com, kwilczynski@kernel.org, david.m.ertman@intel.com, ira.weiny@intel.com, leon@kernel.org, acourbot@nvidia.com, ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org, a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu, pcolberg@redhat.com Cc: rust-for-linux@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Danilo Krummrich Subject: [PATCH 2/8] rust: device: introduce Device::drvdata() Date: Tue, 21 Oct 2025 00:34:24 +0200 Message-ID: <20251020223516.241050-3-dakr@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251020223516.241050-1-dakr@kernel.org> References: <20251020223516.241050-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In C dev_get_drvdata() has specific requirements under which it is valid to access the returned pointer. That is, drivers have to ensure that (1) for the duration the returned pointer is accessed the driver is bound and remains to be bound to the corresponding device, (2) the returned void * is treated according to the driver's private data type, i.e. according to what has been passed to dev_set_drvdata(). In Rust, (1) can be ensured by simply requiring the Bound device context, i.e. provide the drvdata() method for Device only. For (2) we would usually make the device type generic over the driver type, e.g. Device, where ::Data is the type of the driver's private data. However, a device does not have a driver type known at compile time and may be bound to multiple drivers throughout its lifetime. Hence, in order to be able to provide a safe accessor for the driver's device private data, we have to do the type check on runtime. This is achieved by letting a driver assert the expected type, which is then compared to a type hash stored in struct device_private when dev_set_drvdata() is called. Example: // `dev` is a `&Device`. let data =3D dev.drvdata::()?; There are two aspects to note: (1) Technically, the same check could be achieved by comparing the struct device_driver pointer of struct device with the struct device_driver pointer of the driver struct (e.g. struct pci_driver). However, this would - in addition the pointer comparison - require to tie back the private driver data type to the struct device_driver pointer of the driver struct to prove correctness. Besides that, accessing the driver struct (stored in the module structure) isn't trivial and would result into horrible code and API ergonomics. (2) Having a direct accessor to the driver's private data is not commonly required (at least in Rust): Bus callback methods already provide access to the driver's device private data through a &self argument, while other driver entry points such as IRQs, workqueues, timers, IOCTLs, etc. have their own private data with separate ownership and lifetime. In other words, a driver's device private data is only relevant for driver model contexts (such a file private is only relevant for file contexts). Having that said, the motivation for accessing the driver's device private data with Device::drvdata() are interactions between drivers. For instance, when an auxiliary driver calls back into its parent, the parent has to be capable to derive its private data from the corresponding device (i.e. the parent of the auxiliary device). Signed-off-by: Danilo Krummrich Reviewed-by: Alice Ryhl Reviewed-by: Greg Kroah-Hartman --- drivers/base/base.h | 16 +++++++ rust/bindings/bindings_helper.h | 6 +++ rust/kernel/device.rs | 79 +++++++++++++++++++++++++++++++-- 3 files changed, 98 insertions(+), 3 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index 86fa7fbb3548..430cbefbc97f 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -85,6 +85,18 @@ struct driver_private { }; #define to_driver(obj) container_of(obj, struct driver_private, kobj) =20 +#ifdef CONFIG_RUST +/** + * struct driver_type - Representation of a Rust driver type. + */ +struct driver_type { + /** + * @id: Representation of core::any::TypeId. + */ + u8 id[16]; +} __packed; +#endif + /** * struct device_private - structure to hold the private to the driver cor= e portions of the device structure. * @@ -100,6 +112,7 @@ struct driver_private { * @async_driver - pointer to device driver awaiting probe via async_probe * @device - pointer back to the struct device that this structure is * associated with. + * @driver_type - The type of the bound Rust driver. * @dead - This device is currently either in the process of or has been * removed from the system. Any asynchronous events scheduled for this * device should exit without taking any action. @@ -116,6 +129,9 @@ struct device_private { const struct device_driver *async_driver; char *deferred_probe_reason; struct device *device; +#ifdef CONFIG_RUST + struct driver_type driver_type; +#endif u8 dead:1; }; #define to_device_private_parent(obj) \ diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helpe= r.h index 2e43c66635a2..a79fd111f886 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -85,6 +85,12 @@ #include #include =20 +/* + * The driver-core Rust code needs to know about some C driver-core private + * structures. + */ +#include <../../drivers/base/base.h> + #if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE) // Used by `#[export]` in `drivers/gpu/drm/drm_panic_qr.rs`. #include diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs index 106aa57a6385..36c6eec0ceab 100644 --- a/rust/kernel/device.rs +++ b/rust/kernel/device.rs @@ -10,13 +10,19 @@ sync::aref::ARef, types::{ForeignOwnable, Opaque}, }; -use core::{marker::PhantomData, ptr}; +use core::{any::TypeId, marker::PhantomData, ptr}; =20 #[cfg(CONFIG_PRINTK)] use crate::c_str; =20 pub mod property; =20 +// Compile-time checks. +const _: () =3D { + // Assert that we can `read()` / `write()` a `TypeId` instance from / = into `struct driver_type`. + static_assert!(core::mem::size_of::() =3D=3D co= re::mem::size_of::()); +}; + /// The core representation of a device in the kernel's driver model. /// /// This structure represents the Rust abstraction for a C `struct device`= . A [`Device`] can either @@ -198,12 +204,29 @@ pub unsafe fn as_bound(&self) -> &Device { } =20 impl Device { + fn type_id_store(&self) { + // SAFETY: By the type invariants, `self.as_raw()` is a valid poin= ter to a `struct device`. + let private =3D unsafe { (*self.as_raw()).p }; + + // SAFETY: For a bound device (implied by the `CoreInternal` devic= e context), `private` is + // guaranteed to be a valid pointer to a `struct device_private`. + let driver_type =3D unsafe { &raw mut (*private).driver_type }; + + // SAFETY: `driver_type` is valid for (unaligned) writes of a `Typ= eId`. + unsafe { + driver_type + .cast::() + .write_unaligned(TypeId::of::()) + }; + } + /// Store a pointer to the bound driver's private data. pub fn set_drvdata(&self, data: impl PinInit) ->= Result { let data =3D KBox::pin_init(data, GFP_KERNEL)?; =20 // SAFETY: By the type invariants, `self.as_raw()` is a valid poin= ter to a `struct device`. unsafe { bindings::dev_set_drvdata(self.as_raw(), data.into_foreig= n().cast()) }; + self.type_id_store::(); =20 Ok(()) } @@ -235,7 +258,23 @@ pub unsafe fn drvdata_obtain(&self) -> Pin= > { /// [`Device::drvdata_obtain`]. /// - The type `T` must match the type of the `ForeignOwnable` previou= sly stored by /// [`Device::set_drvdata`]. - pub unsafe fn drvdata_borrow(&self) -> T::Borrowed<= '_> { + pub unsafe fn drvdata_borrow(&self) -> Pin<&T> { + // SAFETY: `drvdata_unchecked()` has the exact same safety require= ments as the ones + // required by this method. + unsafe { self.drvdata_unchecked() } + } +} + +impl Device { + /// Borrow the driver's private data bound to this [`Device`]. + /// + /// # Safety + /// + /// - Must only be called after a preceding call to [`Device::set_drvd= ata`] and before + /// [`Device::drvdata_obtain`]. + /// - The type `T` must match the type of the `ForeignOwnable` previou= sly stored by + /// [`Device::set_drvdata`]. + unsafe fn drvdata_unchecked(&self) -> Pin<&T> { // SAFETY: By the type invariants, `self.as_raw()` is a valid poin= ter to a `struct device`. let ptr =3D unsafe { bindings::dev_get_drvdata(self.as_raw()) }; =20 @@ -244,7 +283,41 @@ pub unsafe fn drvdata_borrow(&self)= -> T::Borrowed<'_> { // `into_foreign()`. // - `dev_get_drvdata()` guarantees to return the same pointer giv= en to `dev_set_drvdata()` // in `into_foreign()`. - unsafe { T::borrow(ptr.cast()) } + unsafe { Pin::>::borrow(ptr.cast()) } + } + + fn type_id_match(&self) -> Result { + // SAFETY: By the type invariants, `self.as_raw()` is a valid poin= ter to a `struct device`. + let private =3D unsafe { (*self.as_raw()).p }; + + // SAFETY: For a bound device, `private` is guaranteed to be a val= id pointer to a + // `struct device_private`. + let driver_type =3D unsafe { &raw mut (*private).driver_type }; + + // SAFETY: + // - `driver_type` is valid for (unaligned) reads of a `TypeId`. + // - A bound device guarantees that `driver_type` contains a valid= `TypeId` value. + let type_id =3D unsafe { driver_type.cast::().read_unalign= ed() }; + + if type_id !=3D TypeId::of::() { + return Err(EINVAL); + } + + Ok(()) + } + + /// Access a driver's private data. + /// + /// Returns a pinned reference to the driver's private data or [`EINVA= L`] if it doesn't match + /// the asserted type `T`. + pub fn drvdata(&self) -> Result> { + self.type_id_match::()?; + + // SAFETY: + // - The `Bound` device context guarantees that this is only ever = call after a call + // to `set_drvdata()` and before `drvdata_obtain()`. + // - We've just checked that the type of the driver's private data= is in fact `T`. + Ok(unsafe { self.drvdata_unchecked() }) } } =20 --=20 2.51.0 From nobody Sat Feb 7 23:23:03 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0AC572F2909; Mon, 20 Oct 2025 22:35:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999750; cv=none; b=h4HNHY2VQvQ+pzcTpFYFtyyJqWS0sljKsS9rCanLn+ZywQnp91OxrKJe1Mh9KuOjY3JI8TYaXIUjEK2kK9VObGaFjhNCAtSFGXAYkRrQG/ATh74AjywmJ0woIdQVCPKdF7Gxwr7ZTamYObOnuFAWSsycpHReaph6Q9NHqsWRrn4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999750; c=relaxed/simple; bh=ztSeCB3sZ4feAtMAomRbrXlR9m47mCxeryRJO8qptqA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VFkr3z/2kh1hs0Mr82PgxJ4qqNqelN40r5BoHgf4Ky9hIHb+fzflU76hza7FM5l9dTmWgBw4rGCcbVG/o6K/0ypziC6wWJ394l57BtJktwDvfF/EUbmkc1oz7IW9ygvnkQsbMngpwJf2/Su6rVhht9vS2c7VWkIv4Psm4jW2Y+w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=B39RaM8Q; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="B39RaM8Q" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 68880C4CEFB; Mon, 20 Oct 2025 22:35:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760999747; bh=ztSeCB3sZ4feAtMAomRbrXlR9m47mCxeryRJO8qptqA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=B39RaM8Qlzp/vhiEeWOt5zr+rVxT6Ag2y8at6PjMyzB5uoJ5uFnbVdMbhPIPRiNj5 WlQRYlqjMKU/oxy3Io9K0Teq/N5iLwn28e0J4agiR7nNRZ5Q4uY6cU1WI7lMuEFKC5 rv8PYReDDwo/iXE0S+sZCDk53nhJsOYBCjb6sDvLlpzz1mdTHSOkzuVQvSuml994ig P350dsrWePcP7/iwwnIvLxDja6XQc+exk4y5ptBDrXbTd8CK51FTCzXwCqvyt0jns2 KmB82/DDcqNjTaHCdKQhB95TrvFQeOxX3bSvAZA55shB/VKMTAXQocZlDHeYHXVI+D Tq5NNBt99b4qQ== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, bhelgaas@google.com, kwilczynski@kernel.org, david.m.ertman@intel.com, ira.weiny@intel.com, leon@kernel.org, acourbot@nvidia.com, ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org, a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu, pcolberg@redhat.com Cc: rust-for-linux@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Danilo Krummrich Subject: [PATCH 3/8] rust: auxiliary: consider auxiliary devices always have a parent Date: Tue, 21 Oct 2025 00:34:25 +0200 Message-ID: <20251020223516.241050-4-dakr@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251020223516.241050-1-dakr@kernel.org> References: <20251020223516.241050-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" An auxiliary device is guaranteed to always have a parent device (both in C and Rust), hence don't return an Option<&auxiliary::Device> in auxiliary::Device::parent(). Signed-off-by: Danilo Krummrich Reviewed-by: Alice Ryhl Reviewed-by: Greg Kroah-Hartman --- drivers/gpu/drm/nova/file.rs | 2 +- rust/kernel/auxiliary.rs | 7 ++++--- samples/rust/rust_driver_auxiliary.rs | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nova/file.rs b/drivers/gpu/drm/nova/file.rs index 90b9d2d0ec4a..a3b7bd36792c 100644 --- a/drivers/gpu/drm/nova/file.rs +++ b/drivers/gpu/drm/nova/file.rs @@ -28,7 +28,7 @@ pub(crate) fn get_param( _file: &drm::File, ) -> Result { let adev =3D &dev.adev; - let parent =3D adev.parent().ok_or(ENOENT)?; + let parent =3D adev.parent(); let pdev: &pci::Device =3D parent.try_into()?; =20 let value =3D match getparam.param as u32 { diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs index a6a2b23befce..e5bddb738d58 100644 --- a/rust/kernel/auxiliary.rs +++ b/rust/kernel/auxiliary.rs @@ -215,9 +215,10 @@ pub fn id(&self) -> u32 { unsafe { (*self.as_raw()).id } } =20 - /// Returns a reference to the parent [`device::Device`], if any. - pub fn parent(&self) -> Option<&device::Device> { - self.as_ref().parent() + /// Returns a reference to the parent [`device::Device`]. + pub fn parent(&self) -> &device::Device { + // SAFETY: A `struct auxiliary_device` always has a parent. + unsafe { self.as_ref().parent().unwrap_unchecked() } } } =20 diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driv= er_auxiliary.rs index 0e221abe4936..2e9afeb83d4f 100644 --- a/samples/rust/rust_driver_auxiliary.rs +++ b/samples/rust/rust_driver_auxiliary.rs @@ -68,7 +68,7 @@ fn probe(pdev: &pci::Device, _info: &Self::IdInfo) = -> impl PinInit Result<()> { - let parent =3D adev.parent().ok_or(EINVAL)?; + let parent =3D adev.parent(); let pdev: &pci::Device =3D parent.try_into()?; =20 let vendor =3D pdev.vendor_id(); --=20 2.51.0 From nobody Sat Feb 7 23:23:03 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 73DBD2F3C38; Mon, 20 Oct 2025 22:35:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999752; cv=none; b=H2jDfngGw5eQLlCrYWTH6BAB/X9r6715+cwafyW6E15A1xKbOBBkWq4RkrZIOMPAkIxtx3la38L3MG2MSFP/13Fe8PHrChpjCIc2GdScFgswM1i/5B/F77sw58W9hUyDZdtjhBT3LZ6KNyF26HRrsMZ1TRSp2bPVUgaKo6YZ2fU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999752; c=relaxed/simple; bh=5W2Rc7W4plwT9rV2E/o75Pa4S1pZCmfpN1yvJ6DOa5U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WumsTZWFoRAx/VJHcJWvBMIhM0Aj070sRsCgM5QGLMqbzK3gYf4/o9HOys8iwhduZZJLooJJv4gI9kIPMiPfjp5vIkRC436E94B7/82xMTMDF4V4q9vngXRE3/o7wfLP66oaeoH+NEVvfidxwlfULn9xv7Hzo3GZVCwiH/K3OLY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ezjbZV7f; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ezjbZV7f" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1A042C116C6; Mon, 20 Oct 2025 22:35:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760999752; bh=5W2Rc7W4plwT9rV2E/o75Pa4S1pZCmfpN1yvJ6DOa5U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ezjbZV7fD/n+h+Cw3+4SwhHrCbO7HJOZ5NuMsmqAfQIS8YjaF0/3/icq4qs85gQr6 zEwAm6gBLoXbISfOjW6Da3rguugidtlR1Xs6PHMtlWdxEBDx4eM2jsYV3PmF9UfnJz Trtg+nEHoeQvCJNVA47z+IGgNQCCQB+FeK88YZy4RYxLZ1RSVvSWqUECechVRizb2n UczIeXRMO1/tRd7JIhNhCh0q1MxuXUdY9CkaZsk2lKZE1MznYF0HhMQ4efB5LsWAu8 wJtIdL549wyGeFQurGNla7iPOKnhjH/99erECAFvwTonE/YvswCTyqelh3EH1OF9+U m8iOUbQzR6raQ== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, bhelgaas@google.com, kwilczynski@kernel.org, david.m.ertman@intel.com, ira.weiny@intel.com, leon@kernel.org, acourbot@nvidia.com, ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org, a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu, pcolberg@redhat.com Cc: rust-for-linux@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Danilo Krummrich Subject: [PATCH 4/8] rust: auxiliary: unregister on parent device unbind Date: Tue, 21 Oct 2025 00:34:26 +0200 Message-ID: <20251020223516.241050-5-dakr@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251020223516.241050-1-dakr@kernel.org> References: <20251020223516.241050-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Guarantee that an auxiliary driver will be unbound before its parent is unbound; there is no point in operating an auxiliary device whose parent has been unbound. In practice, this guarantee allows us to assume that for a bound auxiliary device, also the parent device is bound. This is useful when an auxiliary driver calls into its parent, since it allows the parent to directly access device resources and its device private data due to the guaranteed bound device context. Signed-off-by: Danilo Krummrich Reviewed-by: Alice Ryhl Reviewed-by: Greg Kroah-Hartman --- drivers/gpu/nova-core/driver.rs | 8 ++- rust/kernel/auxiliary.rs | 89 +++++++++++++++------------ samples/rust/rust_driver_auxiliary.rs | 17 ++--- 3 files changed, 66 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver= .rs index a83b86199182..ca0d5f8ad54b 100644 --- a/drivers/gpu/nova-core/driver.rs +++ b/drivers/gpu/nova-core/driver.rs @@ -3,6 +3,7 @@ use kernel::{ auxiliary, c_str, device::Core, + devres::Devres, pci, pci::{Class, ClassMask, Vendor}, prelude::*, @@ -16,7 +17,8 @@ pub(crate) struct NovaCore { #[pin] pub(crate) gpu: Gpu, - _reg: auxiliary::Registration, + #[pin] + _reg: Devres, } =20 const BAR0_SIZE: usize =3D SZ_16M; @@ -65,12 +67,12 @@ fn probe(pdev: &pci::Device, _info: &Self::IdInfo= ) -> impl PinInit Result { - let boxed =3D KBox::new(Opaque::::zero= ed(), GFP_KERNEL)?; - let adev =3D boxed.get(); + pub fn new<'a>( + parent: &'a device::Device, + name: &'a CStr, + id: u32, + modname: &'a CStr, + ) -> impl PinInit, Error> + 'a { + pin_init::pin_init_scope(move || { + let boxed =3D KBox::new(Opaque::::= zeroed(), GFP_KERNEL)?; + let adev =3D boxed.get(); + + // SAFETY: It's safe to set the fields of `struct auxiliary_de= vice` on initialization. + unsafe { + (*adev).dev.parent =3D parent.as_raw(); + (*adev).dev.release =3D Some(Device::release); + (*adev).name =3D name.as_char_ptr(); + (*adev).id =3D id; + } =20 - // SAFETY: It's safe to set the fields of `struct auxiliary_device= ` on initialization. - unsafe { - (*adev).dev.parent =3D parent.as_raw(); - (*adev).dev.release =3D Some(Device::release); - (*adev).name =3D name.as_char_ptr(); - (*adev).id =3D id; - } - - // SAFETY: `adev` is guaranteed to be a valid pointer to a `struct= auxiliary_device`, - // which has not been initialized yet. - unsafe { bindings::auxiliary_device_init(adev) }; - - // Now that `adev` is initialized, leak the `Box`; the correspondi= ng memory will be freed - // by `Device::release` when the last reference to the `struct aux= iliary_device` is dropped. - let _ =3D KBox::into_raw(boxed); - - // SAFETY: - // - `adev` is guaranteed to be a valid pointer to a `struct auxil= iary_device`, which has - // been initialialized, - // - `modname.as_char_ptr()` is a NULL terminated string. - let ret =3D unsafe { bindings::__auxiliary_device_add(adev, modnam= e.as_char_ptr()) }; - if ret !=3D 0 { // SAFETY: `adev` is guaranteed to be a valid pointer to a `st= ruct auxiliary_device`, - // which has been initialialized. - unsafe { bindings::auxiliary_device_uninit(adev) }; - - return Err(Error::from_errno(ret)); - } - - // SAFETY: `adev` is guaranteed to be non-null, since the `KBox` w= as allocated successfully. - // - // INVARIANT: The device will remain registered until `auxiliary_d= evice_delete()` is called, - // which happens in `Self::drop()`. - Ok(Self(unsafe { NonNull::new_unchecked(adev) })) + // which has not been initialized yet. + unsafe { bindings::auxiliary_device_init(adev) }; + + // Now that `adev` is initialized, leak the `Box`; the corresp= onding memory will be + // freed by `Device::release` when the last reference to the `= struct auxiliary_device` + // is dropped. + let _ =3D KBox::into_raw(boxed); + + // SAFETY: + // - `adev` is guaranteed to be a valid pointer to a `struct a= uxiliary_device`, which + // has been initialized, + // - `modname.as_char_ptr()` is a NULL terminated string. + let ret =3D unsafe { bindings::__auxiliary_device_add(adev, mo= dname.as_char_ptr()) }; + if ret !=3D 0 { + // SAFETY: `adev` is guaranteed to be a valid pointer to a + // `struct auxiliary_device`, which has been initialized. + unsafe { bindings::auxiliary_device_uninit(adev) }; + + return Err(Error::from_errno(ret)); + } + + // SAFETY: `adev` is guaranteed to be non-null, since the `KBo= x` was allocated + // successfully. + // + // INVARIANT: The device will remain registered until `auxilia= ry_device_delete()` is + // called, which happens in `Self::drop()`. + Ok(Devres::new( + parent, + Self(unsafe { NonNull::new_unchecked(adev) }), + )) + }) } } =20 diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driv= er_auxiliary.rs index 2e9afeb83d4f..95c552ee9489 100644 --- a/samples/rust/rust_driver_auxiliary.rs +++ b/samples/rust/rust_driver_auxiliary.rs @@ -5,7 +5,8 @@ //! To make this driver probe, QEMU must be run with `-device pci-testdev`. =20 use kernel::{ - auxiliary, c_str, device::Core, driver, error::Error, pci, prelude::*,= InPlaceModule, + auxiliary, c_str, device::Core, devres::Devres, driver, error::Error, = pci, prelude::*, + InPlaceModule, }; =20 use pin_init::PinInit; @@ -40,8 +41,12 @@ fn probe(adev: &auxiliary::Device, _info: &Self::I= dInfo) -> impl PinInit, + #[pin] + _reg1: Devres, } =20 kernel::pci_device_table!( @@ -57,11 +62,9 @@ impl pci::Driver for ParentDriver { const ID_TABLE: pci::IdTable =3D &PCI_TABLE; =20 fn probe(pdev: &pci::Device, _info: &Self::IdInfo) -> impl PinIn= it { - Ok(Self { - _reg: [ - auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME= , 0, MODULE_NAME)?, - auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME= , 1, MODULE_NAME)?, - ], + try_pin_init!(Self { + _reg0 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY= _NAME, 0, MODULE_NAME), + _reg1 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY= _NAME, 1, MODULE_NAME), }) } } --=20 2.51.0 From nobody Sat Feb 7 23:23:03 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 60F342F2916; Mon, 20 Oct 2025 22:35:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999757; cv=none; b=VL9GjYXvS8V8ZbjviaKsOtNlCx2ZdTbR7DrO3cIdnz9smgVR83O9t0teumjkRilHZlfkYqa1wBeMCw8yB5TPgZ5lUN5ec1nNClS/ATgtEmOrpBI2g5nj0MYheTmPhmxxvoCqnsVEsOUjjV1i3JmcetE9EGyIBk/Aot+UAofzF9U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999757; c=relaxed/simple; bh=mpG5xoWCQZD3UulIuc3X/ziKsLxEWBQwq/RQZw4SiIE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aexMMYnybXlSfBiSkOY6FhhuZam1ZtlQ/Vpa6ybPcppeeQ30ywzF1lVItwep+8UO/E+7TflskIg5Fi8FwOOkgKviEuau9URnWu9Gu2Eff+TzkjZtNE8X/F5ziPNpWaEE4UPQ/Y1X5KWTn5PiPAODgjKvU+SAKAmSNMI8RoHOTMo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RH4kT+yg; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RH4kT+yg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BE3F2C113D0; Mon, 20 Oct 2025 22:35:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760999757; bh=mpG5xoWCQZD3UulIuc3X/ziKsLxEWBQwq/RQZw4SiIE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RH4kT+ygl25+07mFqPnKK3XVjzsVFZRyx+BdGJP4tUONSuPNLCK47lrRINNa5Cp/7 cM83JwuT9FNn4uqrM8pEh8HB6tf58FDgBk7j/WtgSaF610YK8sBZI5EOQHmDHqTnPD FsbgMaEH8fwW3spCgNb8TIKWQ6f6Y3Qj3vG0QWBYgoXzEawN6fHRVlgt1MPipszhlI PoEQhV1Xe4r7Vl4bVu1kqE7I/3ScRLeIAWQosvojPIQzTwWxAeRu9mn7qlPcmVuvpv xYG3UPZL92ChOegkNPObPXdnBw2/HZfPn3IAEKU11TtDL2Up5xh40mvQGnxTF9lpnl zvUVDilPLLhjw== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, bhelgaas@google.com, kwilczynski@kernel.org, david.m.ertman@intel.com, ira.weiny@intel.com, leon@kernel.org, acourbot@nvidia.com, ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org, a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu, pcolberg@redhat.com Cc: rust-for-linux@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Danilo Krummrich Subject: [PATCH 5/8] rust: auxiliary: move parent() to impl Device Date: Tue, 21 Oct 2025 00:34:27 +0200 Message-ID: <20251020223516.241050-6-dakr@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251020223516.241050-1-dakr@kernel.org> References: <20251020223516.241050-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently, the parent method is implemented for any Device, i.e. any device context and returns a &device::Device. However, a subsequent patch will introduce impl Device { pub fn parent() -> device::Device { ... } } which takes advantage of the fact that if the auxiliary device is bound the parent is guaranteed to be bound as well. I.e. the behavior we want is that all device contexts that dereference to Bound, will use the implementation above, whereas the old implementation should only be implemented for Device. Hence, move the current implementation. Signed-off-by: Danilo Krummrich Reviewed-by: Alice Ryhl Reviewed-by: Greg Kroah-Hartman --- rust/kernel/auxiliary.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs index 8c0a2472c26a..497601f7473b 100644 --- a/rust/kernel/auxiliary.rs +++ b/rust/kernel/auxiliary.rs @@ -215,15 +215,15 @@ pub fn id(&self) -> u32 { // `struct auxiliary_device`. unsafe { (*self.as_raw()).id } } +} =20 +impl Device { /// Returns a reference to the parent [`device::Device`]. pub fn parent(&self) -> &device::Device { // SAFETY: A `struct auxiliary_device` always has a parent. unsafe { self.as_ref().parent().unwrap_unchecked() } } -} =20 -impl Device { extern "C" fn release(dev: *mut bindings::device) { // SAFETY: By the type invariant `self.0.as_raw` is a pointer to t= he `struct device` // embedded in `struct auxiliary_device`. --=20 2.51.0 From nobody Sat Feb 7 23:23:03 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 13D6E2F361E; Mon, 20 Oct 2025 22:36:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999763; cv=none; b=ogv1tjkZi/vruh0G0lhUu99nPa4hAIqo5sf+IEWu64885hSL2dvv9sOLdaHSiSl3UvPIdltC+InhYlbu+0hV5cy/4BMbsst1dR/mpHShk0Otw3iPtcnehkP0Fy6AaKcloT4SP4uClPqQ4miSqXPIy4/4LbCi05+3PDFIaOtlxpw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999763; c=relaxed/simple; bh=sO3O0omt7VKS/7RVAA++jwgQ7zwKtYLTJkPtXBm8Lbs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZxMxTOxfTe8m5dkGWx76+juub2Qkl6Oh2ULzgN0R8ZA3fQgGQglC5+yyooXYM/2t8+frnuBNeFeEZ0DR57lXaahtBsG/d5dsBftfRFS2YJYlOOAXEgRXH4C/hEdGT5hpCwVAfqqFaPGLR6B042nf2zCbaj0CL5vax3rnBHHHZD0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=exq2ePS/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="exq2ePS/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6F642C116C6; Mon, 20 Oct 2025 22:35:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760999761; bh=sO3O0omt7VKS/7RVAA++jwgQ7zwKtYLTJkPtXBm8Lbs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=exq2ePS/jWSVyd7oknEY4BI0hbbn37Chp2L+H97DLqoTCODI3ntzjAzEm/Rzna506 xlsUlWQbvwc5QrWqiK49rAHUhCw40MhOCN1sskk6IfpKttLwFnkv0f1yJgZCGdkYuu INIFSsFUUi2BA22AubbIn+MesEGto2qQyem/l7UPCeQNOdIoH+PJ+vK8dQXY0uVb6j MBuOQN2VW47uhO0rOtKk7FWjR8Wz/FNb+nFp32rHgtDU125nOMeffz/6XfeNT/s46k kvcSvNXAgdcFKEf9nyqbBn6h+7xPVvfOPqR5Da2a0+a4356y1lZjReo4lhaj2ar7Jd YiP7K/hn1MHdw== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, bhelgaas@google.com, kwilczynski@kernel.org, david.m.ertman@intel.com, ira.weiny@intel.com, leon@kernel.org, acourbot@nvidia.com, ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org, a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu, pcolberg@redhat.com Cc: rust-for-linux@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Danilo Krummrich Subject: [PATCH 6/8] rust: auxiliary: implement parent() for Device Date: Tue, 21 Oct 2025 00:34:28 +0200 Message-ID: <20251020223516.241050-7-dakr@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251020223516.241050-1-dakr@kernel.org> References: <20251020223516.241050-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Take advantage of the fact that if the auxiliary device is bound the parent is guaranteed to be bound as well and implement a separate parent() method for auxiliary::Device. Signed-off-by: Danilo Krummrich Reviewed-by: Alice Ryhl Reviewed-by: Greg Kroah-Hartman --- rust/kernel/auxiliary.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs index 497601f7473b..cc67fa5ddde3 100644 --- a/rust/kernel/auxiliary.rs +++ b/rust/kernel/auxiliary.rs @@ -217,6 +217,16 @@ pub fn id(&self) -> u32 { } } =20 +impl Device { + /// Returns a bound reference to the parent [`device::Device`]. + pub fn parent(&self) -> &device::Device { + let parent =3D (**self).parent(); + + // SAFETY: A bound auxiliary device always has a bound parent devi= ce. + unsafe { parent.as_bound() } + } +} + impl Device { /// Returns a reference to the parent [`device::Device`]. pub fn parent(&self) -> &device::Device { --=20 2.51.0 From nobody Sat Feb 7 23:23:03 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CA9462E9EC9; Mon, 20 Oct 2025 22:36:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999767; cv=none; b=M6KzEYHp+uLkDZs25Ybbtz0LeWTBOTsPlC3gK7Lxwqbfe4AJL4wx9WHBYi++VfBDFnwvxww7H750GQYMMMPI1zFXtCRMajUfKh7y3aNcPbfIEypwGp9nQLEjQ6HMfohfJY5YobXtHE7BbsnASV2X7sKm0XDX5c4mvM3/8k5QE8U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999767; c=relaxed/simple; bh=1IXPs04K4C82DSjxeOYDUizUYaX914ahcPYa0ZilGgQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RWxV6pTPhtzArTqotkX1eYldks2JQhm+hfX+FzF4aRJiag7grS4bJXpAJx2aoecBOUSEJyedHIr1FIRSvDHd45OZp444hPNZtybWoJNexT6/xuPTPGTLu9GPVpsr04yt9FgcuZs2JeNydj27tv3+jW6Y3EUbBg5XMhvZjdUEhyg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TsVF+N2V; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TsVF+N2V" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1F08FC4CEFB; Mon, 20 Oct 2025 22:36:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760999766; bh=1IXPs04K4C82DSjxeOYDUizUYaX914ahcPYa0ZilGgQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TsVF+N2Vm+qNT2bWdZ5cwFFxAJVXjDGQS61hLq2IFJrVInqCtTyK5Kxo4eZfzpM4J y8e99eqMymIDcT/pVVtrI9NL92+zNxYTl1R1R//0vdFyK7XOhIyvOIFTyhaAy+m1RC v2VfHa6a/hjjIo9o/8PO8eaw3X+bp5xBrS7CvubZ9/WHuZhLDLK/ROUaLvE6RAGvsH R1fry9vO+fr/b/tZqVsjRBQTvWJMbhr7lJm916+crRborQNgmFPtL+K9y8eyynSLW+ 1ZuGUFTyx6rmQFEoVg0a1iwFHtC7MM1OVkkhQ5YdLOOJCeNJeMOFeSfNj0UBbeu13c 5GuuytC2Ud5Ag== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, bhelgaas@google.com, kwilczynski@kernel.org, david.m.ertman@intel.com, ira.weiny@intel.com, leon@kernel.org, acourbot@nvidia.com, ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org, a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu, pcolberg@redhat.com Cc: rust-for-linux@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Danilo Krummrich Subject: [PATCH 7/8] samples: rust: auxiliary: misc cleanup of ParentDriver::connect() Date: Tue, 21 Oct 2025 00:34:29 +0200 Message-ID: <20251020223516.241050-8-dakr@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251020223516.241050-1-dakr@kernel.org> References: <20251020223516.241050-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In ParentDriver::connect() rename parent to dev, use it for the dev_info!() call, call pdev.vendor_() directly in the print statement and remove the unnecessary generic type of Result. Signed-off-by: Danilo Krummrich Reviewed-by: Alice Ryhl Reviewed-by: Greg Kroah-Hartman --- samples/rust/rust_driver_auxiliary.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driv= er_auxiliary.rs index 95c552ee9489..a5d67d4d9e83 100644 --- a/samples/rust/rust_driver_auxiliary.rs +++ b/samples/rust/rust_driver_auxiliary.rs @@ -70,16 +70,15 @@ fn probe(pdev: &pci::Device, _info: &Self::IdInfo= ) -> impl PinInit Result<()> { - let parent =3D adev.parent(); - let pdev: &pci::Device =3D parent.try_into()?; + fn connect(adev: &auxiliary::Device) -> Result { + let dev =3D adev.parent(); + let pdev: &pci::Device =3D dev.try_into()?; =20 - let vendor =3D pdev.vendor_id(); dev_info!( - adev.as_ref(), + dev, "Connect auxiliary {} with parent: VendorID=3D{}, DeviceID=3D{= :#x}\n", adev.id(), - vendor, + pdev.vendor_id(), pdev.device_id() ); =20 --=20 2.51.0 From nobody Sat Feb 7 23:23:03 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8057A33343E; Mon, 20 Oct 2025 22:36:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999771; cv=none; b=YdglPUwMbYO7vEtOcBwOoRk6p57REzPkQKHFqzYEwsAewt9C31avsd1xwPyvavEcNisXcUa98i6kuddXn6N4rKL7NE9EjcOYhquJjG6bWvP6wCOKF4fdFozbuYhkU1Q0YN4UOBeiWP8uyekBJm/TfZF/7a0Rr3lJlyVJDNDesaA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760999771; c=relaxed/simple; bh=QxGK4UEFzt4WjxckGXtrR7+T4t6vEtOAH7gCnrjQeow=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jCV6iyXZGv7PbVtu2Lr8by2qOhs3M/h0v2BRuYw9Vx5LI1o08Ca/LeUqSxya1sSrvqx9mrM2PQ6wZVAhgL13GQ//fCtN62uZautxueO7NGRgPX3R0dxc46e1nndoAfSW+2djprLX1i8Y2vF+DdyjNCI4uhVLzl6q8l8qe2QMiBY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ssaEuPZ4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ssaEuPZ4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C37F9C116C6; Mon, 20 Oct 2025 22:36:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760999771; bh=QxGK4UEFzt4WjxckGXtrR7+T4t6vEtOAH7gCnrjQeow=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ssaEuPZ4oOxv9g2hn1GLCbgTX8Aqn2hwpeHezcOC9AUh2TBRpwazxGnNHdmh+YvmU 9OoXJOGYA4mcfBscwNrNlusxEtEObzdVVBrcihS8axS1n6Dn9H1k13vYqGywxZOW0Z xEPkhY02w72g6LxbspznwJFnPKEzu2oLYTxHeLZImnPFvk6UnGWOMJjHGYqGdR9k5+ wdRkKMWie6cA+EIxEo7Pw/A70Hcc+GygNAdhnritquR+6gef9GcVhsom7cY4YlQxip T1hM+Z0HFv/WS4I27zy2el1ibKMH55mpdlEgdnhZS/lvEeGrxvvf8AWM6Gxft0QT0g z9dbO5jewKVHA== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, bhelgaas@google.com, kwilczynski@kernel.org, david.m.ertman@intel.com, ira.weiny@intel.com, leon@kernel.org, acourbot@nvidia.com, ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org, a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu, pcolberg@redhat.com Cc: rust-for-linux@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Danilo Krummrich Subject: [PATCH 8/8] samples: rust: auxiliary: illustrate driver interaction Date: Tue, 21 Oct 2025 00:34:30 +0200 Message-ID: <20251020223516.241050-9-dakr@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251020223516.241050-1-dakr@kernel.org> References: <20251020223516.241050-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Illustrate how a parent driver of an auxiliary driver can take advantage of the device context guarantees given by the auxiliary bus and subsequently safely derive its device private data. Signed-off-by: Danilo Krummrich Reviewed-by: Alice Ryhl Reviewed-by: Greg Kroah-Hartman --- samples/rust/rust_driver_auxiliary.rs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driv= er_auxiliary.rs index a5d67d4d9e83..5761ea314f44 100644 --- a/samples/rust/rust_driver_auxiliary.rs +++ b/samples/rust/rust_driver_auxiliary.rs @@ -5,10 +5,17 @@ //! To make this driver probe, QEMU must be run with `-device pci-testdev`. =20 use kernel::{ - auxiliary, c_str, device::Core, devres::Devres, driver, error::Error, = pci, prelude::*, + auxiliary, c_str, + device::{Bound, Core}, + devres::Devres, + driver, + error::Error, + pci, + prelude::*, InPlaceModule, }; =20 +use core::any::TypeId; use pin_init::PinInit; =20 const MODULE_NAME: &CStr =3D ::NAME; @@ -43,6 +50,7 @@ fn probe(adev: &auxiliary::Device, _info: &Self::Id= Info) -> impl PinInit, #[pin] @@ -63,6 +71,7 @@ impl pci::Driver for ParentDriver { =20 fn probe(pdev: &pci::Device, _info: &Self::IdInfo) -> impl PinIn= it { try_pin_init!(Self { + private: TypeId::of::(), _reg0 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY= _NAME, 0, MODULE_NAME), _reg1 <- auxiliary::Registration::new(pdev.as_ref(), AUXILIARY= _NAME, 1, MODULE_NAME), }) @@ -70,9 +79,10 @@ fn probe(pdev: &pci::Device, _info: &Self::IdInfo)= -> impl PinInit Result { + fn connect(adev: &auxiliary::Device) -> Result { let dev =3D adev.parent(); - let pdev: &pci::Device =3D dev.try_into()?; + let pdev: &pci::Device =3D dev.try_into()?; + let drvdata =3D dev.drvdata::()?; =20 dev_info!( dev, @@ -82,6 +92,12 @@ fn connect(adev: &auxiliary::Device) -> Result { pdev.device_id() ); =20 + dev_info!( + dev, + "We have access to the private data of {:?}.\n", + drvdata.private + ); + Ok(()) } } --=20 2.51.0