History

Merge tag 'driver-core-6.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core

Pull driver core fixes from Danilo Krummrich: - Always inline I/O and IRQ methods using build_assert!() to avoid false positive build errors - Do not free the driver's device private data in I2C shutdown() avoiding race conditions that can lead to UAF bugs - Drop the driver's device private data after the driver has been fully unbound from its device to avoid UAF bugs from &Device<Bound> scopes, such as IRQ callbacks * tag 'driver-core-6.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core: rust: driver: drop device private data post unbind rust: driver: add DriverData type to the DriverLayout trait rust: driver: add DEVICE_DRIVER_OFFSET to the DriverLayout trait rust: driver: introduce a DriverLayout trait rust: auxiliary: add Driver::unbind() callback rust: i2c: do not drop device private data on shutdown() rust: irq: always inline functions using build_assert with arguments rust: io: always inline functions using build_assert with arguments

Linus Torvalds committed 9 months ago

Commit 5dbeeb22 parents 12a0094 a995fe112 files · +209 −74Browse files

Unified · Split

12 files
  1. drivers/base/dd.c +2 −0
  2. include/linux/device/driver.h +9 −0
  3. rust/kernel/auxiliary.rs +33 −8
  4. rust/kernel/device.rs +11 −9
  5. rust/kernel/driver.rs +70 −16
  6. rust/kernel/i2c.rs +20 −11
  7. rust/kernel/io.rs +6 −3
  8. rust/kernel/io/resource.rs +2 −0
  9. rust/kernel/irq/flags.rs +2 −0
  10. rust/kernel/pci.rs +18 −9
  11. rust/kernel/platform.rs +18 −9
  12. rust/kernel/usb.rs +18 −9
drivers/base/dd.c+2−0
@@ -548,6 +548,8 @@ static DEVICE_ATTR_RW(state_synced); · 547 unmodified lines
548548 static void device_unbind_cleanup(struct device *dev)
549549 {
550550 devres_release_all(dev);
551+ if (dev->driver->p_cb.post_unbind_rust)
552+ dev->driver->p_cb.post_unbind_rust(dev);
551553 arch_teardown_dma_ops(dev);
552554 kfree(dev->dma_range_map);
553555 dev->dma_range_map = NULL;
include/linux/device/driver.h+9−0
@@ -85,6 +85,8 @@ enum probe_type { · 84 unmodified lines
8585 * uevent.
8686 * @p: Driver core's private data, no one other than the driver
8787 * core can touch this.
88+ * @p_cb: Callbacks private to the driver core; no one other than the
89+ * driver core is allowed to touch this.
8890 *
8991 * The device driver-model tracks all of the drivers known to the system.
9092 * The main reason for this tracking is to enable the driver core to match
@@ -119,6 +121,13 @@ struct device_driver { · 28 unmodified lines
119121 void (*coredump) (struct device *dev);
120122
121123 struct driver_private *p;
124+ struct {
125+ /*
126+ * Called after remove() and after all devres entries have been
127+ * processed. This is a Rust only callback.
128+ */
129+ void (*post_unbind_rust)(struct device *dev);
130+ } p_cb;
122131 };
123132
124133
rust/kernel/auxiliary.rs+33−8
@@ -23,13 +23,22 @@ use core::{ · 22 unmodified lines
2323 /// An adapter for the registration of auxiliary drivers.
2424 pub struct Adapter<T: Driver>(T);
2525
26−// SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if
26+// SAFETY:
27+// - `bindings::auxiliary_driver` is a C type declared as `repr(C)`.
28+// - `T` is the type of the driver's device private data.
29+// - `struct auxiliary_driver` embeds a `struct device_driver`.
30+// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
31+unsafe impl<T: Driver + 'static> driver::DriverLayout for Adapter<T> {
32+ type DriverType = bindings::auxiliary_driver;
33+ type DriverData = T;
34+ const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
35+}
36+
37+// SAFETY: A call to `unregister` for a given instance of `DriverType` is guaranteed to be valid if
2738 // a preceding call to `register` has been successful.
2839 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
29− type RegType = bindings::auxiliary_driver;
30−
3140 unsafe fn register(
32− adrv: &Opaque<Self::RegType>,
41+ adrv: &Opaque<Self::DriverType>,
3342 name: &'static CStr,
3443 module: &'static ThisModule,
3544 ) -> Result {
@@ -41,14 +50,14 @@ unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { · 5 unmodified lines
4150 (*adrv.get()).id_table = T::ID_TABLE.as_ptr();
4251 }
4352
44− // SAFETY: `adrv` is guaranteed to be a valid `RegType`.
53+ // SAFETY: `adrv` is guaranteed to be a valid `DriverType`.
4554 to_result(unsafe {
4655 bindings::__auxiliary_driver_register(adrv.get(), module.0, name.as_char_ptr())
4756 })
4857 }
4958
50− unsafe fn unregister(adrv: &Opaque<Self::RegType>) {
51− // SAFETY: `adrv` is guaranteed to be a valid `RegType`.
59+ unsafe fn unregister(adrv: &Opaque<Self::DriverType>) {
60+ // SAFETY: `adrv` is guaranteed to be a valid `DriverType`.
5261 unsafe { bindings::auxiliary_driver_unregister(adrv.get()) }
5362 }
5463 }
@@ -87,7 +96,9 @@ impl<T: Driver + 'static> Adapter<T> { · 32 unmodified lines
8796 // SAFETY: `remove_callback` is only ever called after a successful call to
8897 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
8998 // and stored a `Pin<KBox<T>>`.
90− drop(unsafe { adev.as_ref().drvdata_obtain::<T>() });
99+ let data = unsafe { adev.as_ref().drvdata_borrow::<T>() };
100+
101+ T::unbind(adev, data);
91102 }
92103 }
93104
@@ -187,6 +198,20 @@ pub trait Driver { · 93 unmodified lines
187198 ///
188199 /// Called when an auxiliary device is matches a corresponding driver.
189200 fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> impl PinInit<Self, Error>;
201+
202+ /// Auxiliary driver unbind.
203+ ///
204+ /// Called when a [`Device`] is unbound from its bound [`Driver`]. Implementing this callback
205+ /// is optional.
206+ ///
207+ /// This callback serves as a place for drivers to perform teardown operations that require a
208+ /// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O
209+ /// operations to gracefully tear down the device.
210+ ///
211+ /// Otherwise, release operations for driver resources should be performed in `Self::drop`.
212+ fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) {
213+ let _ = (dev, this);
214+ }
190215 }
191216
192217 /// The auxiliary device representation.
rust/kernel/device.rs+11−9
@@ -232,30 +232,32 @@ impl Device<CoreInternal> { · 231 unmodified lines
232232 ///
233233 /// # Safety
234234 ///
235− /// - Must only be called once after a preceding call to [`Device::set_drvdata`].
236235 /// - The type `T` must match the type of the `ForeignOwnable` previously stored by
237236 /// [`Device::set_drvdata`].
238− pub unsafe fn drvdata_obtain<T: 'static>(&self) -> Pin<KBox<T>> {
237+ pub(crate) unsafe fn drvdata_obtain<T: 'static>(&self) -> Option<Pin<KBox<T>>> {
239238 // SAFETY: By the type invariants, `self.as_raw()` is a valid pointer to a `struct device`.
240239 let ptr = unsafe { bindings::dev_get_drvdata(self.as_raw()) };
241240
242241 // SAFETY: By the type invariants, `self.as_raw()` is a valid pointer to a `struct device`.
243242 unsafe { bindings::dev_set_drvdata(self.as_raw(), core::ptr::null_mut()) };
244243
244+ if ptr.is_null() {
245+ return None;
246+ }
247+
245248 // SAFETY:
246− // - By the safety requirements of this function, `ptr` comes from a previous call to
247− // `into_foreign()`.
249+ // - If `ptr` is not NULL, it comes from a previous call to `into_foreign()`.
248250 // - `dev_get_drvdata()` guarantees to return the same pointer given to `dev_set_drvdata()`
249251 // in `into_foreign()`.
250− unsafe { Pin::<KBox<T>>::from_foreign(ptr.cast()) }
252+ Some(unsafe { Pin::<KBox<T>>::from_foreign(ptr.cast()) })
251253 }
252254
253255 /// Borrow the driver's private data bound to this [`Device`].
254256 ///
255257 /// # Safety
256258 ///
257− /// - Must only be called after a preceding call to [`Device::set_drvdata`] and before
258− /// [`Device::drvdata_obtain`].
259+ /// - Must only be called after a preceding call to [`Device::set_drvdata`] and before the
260+ /// device is fully unbound.
259261 /// - The type `T` must match the type of the `ForeignOwnable` previously stored by
260262 /// [`Device::set_drvdata`].
261263 pub unsafe fn drvdata_borrow<T: 'static>(&self) -> Pin<&T> {
@@ -271,7 +273,7 @@ impl Device<Bound> { · 9 unmodified lines
271273 /// # Safety
272274 ///
273275 /// - Must only be called after a preceding call to [`Device::set_drvdata`] and before
274− /// [`Device::drvdata_obtain`].
276+ /// the device is fully unbound.
275277 /// - The type `T` must match the type of the `ForeignOwnable` previously stored by
276278 /// [`Device::set_drvdata`].
277279 unsafe fn drvdata_unchecked<T: 'static>(&self) -> Pin<&T> {
@@ -320,7 +322,7 @@ impl Device<Bound> { · 42 unmodified lines
320322
321323 // SAFETY:
322324 // - The above check of `dev_get_drvdata()` guarantees that we are called after
323− // `set_drvdata()` and before `drvdata_obtain()`.
325+ // `set_drvdata()`.
324326 // - We've just checked that the type of the driver's private data is in fact `T`.
325327 Ok(unsafe { self.drvdata_unchecked() })
326328 }
rust/kernel/driver.rs+70−16
@@ -99,23 +99,43 @@ use crate::{acpi, device, of, str::CStr, try_pin_init, types::Opaque, ThisModule · 98 unmodified lines
9999 use core::pin::Pin;
100100 use pin_init::{pin_data, pinned_drop, PinInit};
101101
102+/// Trait describing the layout of a specific device driver.
103+///
104+/// This trait describes the layout of a specific driver structure, such as `struct pci_driver` or
105+/// `struct platform_driver`.
106+///
107+/// # Safety
108+///
109+/// Implementors must guarantee that:
110+/// - `DriverType` is `repr(C)`,
111+/// - `DriverData` is the type of the driver's device private data.
112+/// - `DriverType` embeds a valid `struct device_driver` at byte offset `DEVICE_DRIVER_OFFSET`.
113+pub unsafe trait DriverLayout {
114+ /// The specific driver type embedding a `struct device_driver`.
115+ type DriverType: Default;
116+
117+ /// The type of the driver's device private data.
118+ type DriverData;
119+
120+ /// Byte offset of the embedded `struct device_driver` within `DriverType`.
121+ ///
122+ /// This must correspond exactly to the location of the embedded `struct device_driver` field.
123+ const DEVICE_DRIVER_OFFSET: usize;
124+}
125+
102126 /// The [`RegistrationOps`] trait serves as generic interface for subsystems (e.g., PCI, Platform,
103127 /// Amba, etc.) to provide the corresponding subsystem specific implementation to register /
104−/// unregister a driver of the particular type (`RegType`).
128+/// unregister a driver of the particular type (`DriverType`).
105129 ///
106−/// For instance, the PCI subsystem would set `RegType` to `bindings::pci_driver` and call
130+/// For instance, the PCI subsystem would set `DriverType` to `bindings::pci_driver` and call
107131 /// `bindings::__pci_register_driver` from `RegistrationOps::register` and
108132 /// `bindings::pci_unregister_driver` from `RegistrationOps::unregister`.
109133 ///
110134 /// # Safety
111135 ///
112−/// A call to [`RegistrationOps::unregister`] for a given instance of `RegType` is only valid if a
113−/// preceding call to [`RegistrationOps::register`] has been successful.
114−pub unsafe trait RegistrationOps {
115− /// The type that holds information about the registration. This is typically a struct defined
116− /// by the C portion of the kernel.
117− type RegType: Default;
118−
136+/// A call to [`RegistrationOps::unregister`] for a given instance of `DriverType` is only valid if
137+/// a preceding call to [`RegistrationOps::register`] has been successful.
138+pub unsafe trait RegistrationOps: DriverLayout {
119139 /// Registers a driver.
120140 ///
121141 /// # Safety
@@ -123,7 +143,7 @@ pub unsafe trait RegistrationOps { · 1 unmodified line
123143 /// On success, `reg` must remain pinned and valid until the matching call to
124144 /// [`RegistrationOps::unregister`].
125145 unsafe fn register(
126− reg: &Opaque<Self::RegType>,
146+ reg: &Opaque<Self::DriverType>,
127147 name: &'static CStr,
128148 module: &'static ThisModule,
129149 ) -> Result;
@@ -134,7 +154,7 @@ pub unsafe trait RegistrationOps { · 4 unmodified lines
134154 ///
135155 /// Must only be called after a preceding successful call to [`RegistrationOps::register`] for
136156 /// the same `reg`.
137− unsafe fn unregister(reg: &Opaque<Self::RegType>);
157+ unsafe fn unregister(reg: &Opaque<Self::DriverType>);
138158 }
139159
140160 /// A [`Registration`] is a generic type that represents the registration of some driver type (e.g.
@@ -146,7 +166,7 @@ pub unsafe trait RegistrationOps { · 5 unmodified lines
146166 #[pin_data(PinnedDrop)]
147167 pub struct Registration<T: RegistrationOps> {
148168 #[pin]
149− reg: Opaque<T::RegType>,
169+ reg: Opaque<T::DriverType>,
150170 }
151171
152172 // SAFETY: `Registration` has no fields or methods accessible via `&Registration`, so it is safe to
@@ -157,17 +177,51 @@ unsafe impl<T: RegistrationOps> Sync for Registration<T> {} · 4 unmodified lines
157177 // any thread, so `Registration` is `Send`.
158178 unsafe impl<T: RegistrationOps> Send for Registration<T> {}
159179
160−impl<T: RegistrationOps> Registration<T> {
180+impl<T: RegistrationOps + 'static> Registration<T> {
181+ extern "C" fn post_unbind_callback(dev: *mut bindings::device) {
182+ // SAFETY: The driver core only ever calls the post unbind callback with a valid pointer to
183+ // a `struct device`.
184+ //
185+ // INVARIANT: `dev` is valid for the duration of the `post_unbind_callback()`.
186+ let dev = unsafe { &*dev.cast::<device::Device<device::CoreInternal>>() };
187+
188+ // `remove()` and all devres callbacks have been completed at this point, hence drop the
189+ // driver's device private data.
190+ //
191+ // SAFETY: By the safety requirements of the `Driver` trait, `T::DriverData` is the
192+ // driver's device private data type.
193+ drop(unsafe { dev.drvdata_obtain::<T::DriverData>() });
194+ }
195+
196+ /// Attach generic `struct device_driver` callbacks.
197+ fn callbacks_attach(drv: &Opaque<T::DriverType>) {
198+ let ptr = drv.get().cast::<u8>();
199+
200+ // SAFETY:
201+ // - `drv.get()` yields a valid pointer to `Self::DriverType`.
202+ // - Adding `DEVICE_DRIVER_OFFSET` yields the address of the embedded `struct device_driver`
203+ // as guaranteed by the safety requirements of the `Driver` trait.
204+ let base = unsafe { ptr.add(T::DEVICE_DRIVER_OFFSET) };
205+
206+ // CAST: `base` points to the offset of the embedded `struct device_driver`.
207+ let base = base.cast::<bindings::device_driver>();
208+
209+ // SAFETY: It is safe to set the fields of `struct device_driver` on initialization.
210+ unsafe { (*base).p_cb.post_unbind_rust = Some(Self::post_unbind_callback) };
211+ }
212+
161213 /// Creates a new instance of the registration object.
162214 pub fn new(name: &'static CStr, module: &'static ThisModule) -> impl PinInit<Self, Error> {
163215 try_pin_init!(Self {
164− reg <- Opaque::try_ffi_init(|ptr: *mut T::RegType| {
216+ reg <- Opaque::try_ffi_init(|ptr: *mut T::DriverType| {
165217 // SAFETY: `try_ffi_init` guarantees that `ptr` is valid for write.
166− unsafe { ptr.write(T::RegType::default()) };
218+ unsafe { ptr.write(T::DriverType::default()) };
167219
168220 // SAFETY: `try_ffi_init` guarantees that `ptr` is valid for write, and it has
169221 // just been initialised above, so it's also valid for read.
170− let drv = unsafe { &*(ptr as *const Opaque<T::RegType>) };
222+ let drv = unsafe { &*(ptr as *const Opaque<T::DriverType>) };
223+
224+ Self::callbacks_attach(drv);
171225
172226 // SAFETY: `drv` is guaranteed to be pinned until `T::unregister`.
173227 unsafe { T::register(drv, name, module) }
rust/kernel/i2c.rs+20−11
@@ -92,13 +92,22 @@ macro_rules! i2c_device_table { · 91 unmodified lines
9292 /// An adapter for the registration of I2C drivers.
9393 pub struct Adapter<T: Driver>(T);
9494
95−// SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if
95+// SAFETY:
96+// - `bindings::i2c_driver` is a C type declared as `repr(C)`.
97+// - `T` is the type of the driver's device private data.
98+// - `struct i2c_driver` embeds a `struct device_driver`.
99+// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
100+unsafe impl<T: Driver + 'static> driver::DriverLayout for Adapter<T> {
101+ type DriverType = bindings::i2c_driver;
102+ type DriverData = T;
103+ const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
104+}
105+
106+// SAFETY: A call to `unregister` for a given instance of `DriverType` is guaranteed to be valid if
96107 // a preceding call to `register` has been successful.
97108 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
98− type RegType = bindings::i2c_driver;
99−
100109 unsafe fn register(
101− idrv: &Opaque<Self::RegType>,
110+ idrv: &Opaque<Self::DriverType>,
102111 name: &'static CStr,
103112 module: &'static ThisModule,
104113 ) -> Result {
@@ -133,12 +142,12 @@ unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { · 28 unmodified lines
133142 (*idrv.get()).driver.acpi_match_table = acpi_table;
134143 }
135144
136− // SAFETY: `idrv` is guaranteed to be a valid `RegType`.
145+ // SAFETY: `idrv` is guaranteed to be a valid `DriverType`.
137146 to_result(unsafe { bindings::i2c_register_driver(module.0, idrv.get()) })
138147 }
139148
140− unsafe fn unregister(idrv: &Opaque<Self::RegType>) {
141− // SAFETY: `idrv` is guaranteed to be a valid `RegType`.
149+ unsafe fn unregister(idrv: &Opaque<Self::DriverType>) {
150+ // SAFETY: `idrv` is guaranteed to be a valid `DriverType`.
142151 unsafe { bindings::i2c_del_driver(idrv.get()) }
143152 }
144153 }
@@ -169,9 +178,9 @@ impl<T: Driver + 'static> Adapter<T> { · 24 unmodified lines
169178 // SAFETY: `remove_callback` is only ever called after a successful call to
170179 // `probe_callback`, hence it's guaranteed that `I2cClient::set_drvdata()` has been called
171180 // and stored a `Pin<KBox<T>>`.
172− let data = unsafe { idev.as_ref().drvdata_obtain::<T>() };
181+ let data = unsafe { idev.as_ref().drvdata_borrow::<T>() };
173182
174− T::unbind(idev, data.as_ref());
183+ T::unbind(idev, data);
175184 }
176185
177186 extern "C" fn shutdown_callback(idev: *mut bindings::i2c_client) {
@@ -181,9 +190,9 @@ impl<T: Driver + 'static> Adapter<T> { · 3 unmodified lines
181190 // SAFETY: `shutdown_callback` is only ever called after a successful call to
182191 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
183192 // and stored a `Pin<KBox<T>>`.
184− let data = unsafe { idev.as_ref().drvdata_obtain::<T>() };
193+ let data = unsafe { idev.as_ref().drvdata_borrow::<T>() };
185194
186− T::shutdown(idev, data.as_ref());
195+ T::shutdown(idev, data);
187196 }
188197
189198 /// The [`i2c::IdTable`] of the corresponding driver.
rust/kernel/io.rs+6−3
@@ -142,7 +142,8 @@ macro_rules! define_read { · 141 unmodified lines
142142 /// Bound checks are performed on compile time, hence if the offset is not known at compile
143143 /// time, the build will fail.
144144 $(#[$attr])*
145− #[inline]
145+ // Always inline to optimize out error path of `io_addr_assert`.
146+ #[inline(always)]
146147 pub fn $name(&self, offset: usize) -> $type_name {
147148 let addr = self.io_addr_assert::<$type_name>(offset);
148149
@@ -171,7 +172,8 @@ macro_rules! define_write { · 22 unmodified lines
171172 /// Bound checks are performed on compile time, hence if the offset is not known at compile
172173 /// time, the build will fail.
173174 $(#[$attr])*
174− #[inline]
175+ // Always inline to optimize out error path of `io_addr_assert`.
176+ #[inline(always)]
175177 pub fn $name(&self, value: $type_name, offset: usize) {
176178 let addr = self.io_addr_assert::<$type_name>(offset);
177179
@@ -239,7 +241,8 @@ impl<const SIZE: usize> Io<SIZE> { · 61 unmodified lines
239241 self.addr().checked_add(offset).ok_or(EINVAL)
240242 }
241243
242− #[inline]
244+ // Always inline to optimize out error path of `build_assert`.
245+ #[inline(always)]
243246 fn io_addr_assert<U>(&self, offset: usize) -> usize {
244247 build_assert!(Self::offset_valid::<U>(offset, SIZE));
245248
rust/kernel/io/resource.rs+2−0
@@ -226,6 +226,8 @@ impl Flags { · 225 unmodified lines
226226 /// Resource represents a memory region that must be ioremaped using `ioremap_np`.
227227 pub const IORESOURCE_MEM_NONPOSTED: Flags = Flags::new(bindings::IORESOURCE_MEM_NONPOSTED);
228228
229+ // Always inline to optimize out error path of `build_assert`.
230+ #[inline(always)]
229231 const fn new(value: u32) -> Self {
230232 crate::build_assert!(value as u64 <= c_ulong::MAX as u64);
231233 Flags(value as c_ulong)
rust/kernel/irq/flags.rs+2−0
@@ -96,6 +96,8 @@ impl Flags { · 95 unmodified lines
9696 self.0
9797 }
9898
99+ // Always inline to optimize out error path of `build_assert`.
100+ #[inline(always)]
99101 const fn new(value: u32) -> Self {
100102 build_assert!(value as u64 <= c_ulong::MAX as u64);
101103 Self(value as c_ulong)
rust/kernel/pci.rs+18−9
@@ -50,13 +50,22 @@ pub use self::irq::{ · 49 unmodified lines
5050 /// An adapter for the registration of PCI drivers.
5151 pub struct Adapter<T: Driver>(T);
5252
53−// SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if
53+// SAFETY:
54+// - `bindings::pci_driver` is a C type declared as `repr(C)`.
55+// - `T` is the type of the driver's device private data.
56+// - `struct pci_driver` embeds a `struct device_driver`.
57+// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
58+unsafe impl<T: Driver + 'static> driver::DriverLayout for Adapter<T> {
59+ type DriverType = bindings::pci_driver;
60+ type DriverData = T;
61+ const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
62+}
63+
64+// SAFETY: A call to `unregister` for a given instance of `DriverType` is guaranteed to be valid if
5465 // a preceding call to `register` has been successful.
5566 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
56− type RegType = bindings::pci_driver;
57−
5867 unsafe fn register(
59− pdrv: &Opaque<Self::RegType>,
68+ pdrv: &Opaque<Self::DriverType>,
6069 name: &'static CStr,
6170 module: &'static ThisModule,
6271 ) -> Result {
@@ -68,14 +77,14 @@ unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { · 5 unmodified lines
6877 (*pdrv.get()).id_table = T::ID_TABLE.as_ptr();
6978 }
7079
71− // SAFETY: `pdrv` is guaranteed to be a valid `RegType`.
80+ // SAFETY: `pdrv` is guaranteed to be a valid `DriverType`.
7281 to_result(unsafe {
7382 bindings::__pci_register_driver(pdrv.get(), module.0, name.as_char_ptr())
7483 })
7584 }
7685
77− unsafe fn unregister(pdrv: &Opaque<Self::RegType>) {
78− // SAFETY: `pdrv` is guaranteed to be a valid `RegType`.
86+ unsafe fn unregister(pdrv: &Opaque<Self::DriverType>) {
87+ // SAFETY: `pdrv` is guaranteed to be a valid `DriverType`.
7988 unsafe { bindings::pci_unregister_driver(pdrv.get()) }
8089 }
8190 }
@@ -114,9 +123,9 @@ impl<T: Driver + 'static> Adapter<T> { · 32 unmodified lines
114123 // SAFETY: `remove_callback` is only ever called after a successful call to
115124 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
116125 // and stored a `Pin<KBox<T>>`.
117− let data = unsafe { pdev.as_ref().drvdata_obtain::<T>() };
126+ let data = unsafe { pdev.as_ref().drvdata_borrow::<T>() };
118127
119− T::unbind(pdev, data.as_ref());
128+ T::unbind(pdev, data);
120129 }
121130 }
122131
rust/kernel/platform.rs+18−9
@@ -26,13 +26,22 @@ use core::{ · 25 unmodified lines
2626 /// An adapter for the registration of platform drivers.
2727 pub struct Adapter<T: Driver>(T);
2828
29−// SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if
29+// SAFETY:
30+// - `bindings::platform_driver` is a C type declared as `repr(C)`.
31+// - `T` is the type of the driver's device private data.
32+// - `struct platform_driver` embeds a `struct device_driver`.
33+// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
34+unsafe impl<T: Driver + 'static> driver::DriverLayout for Adapter<T> {
35+ type DriverType = bindings::platform_driver;
36+ type DriverData = T;
37+ const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
38+}
39+
40+// SAFETY: A call to `unregister` for a given instance of `DriverType` is guaranteed to be valid if
3041 // a preceding call to `register` has been successful.
3142 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
32− type RegType = bindings::platform_driver;
33−
3443 unsafe fn register(
35− pdrv: &Opaque<Self::RegType>,
44+ pdrv: &Opaque<Self::DriverType>,
3645 name: &'static CStr,
3746 module: &'static ThisModule,
3847 ) -> Result {
@@ -55,12 +64,12 @@ unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { · 16 unmodified lines
5564 (*pdrv.get()).driver.acpi_match_table = acpi_table;
5665 }
5766
58− // SAFETY: `pdrv` is guaranteed to be a valid `RegType`.
67+ // SAFETY: `pdrv` is guaranteed to be a valid `DriverType`.
5968 to_result(unsafe { bindings::__platform_driver_register(pdrv.get(), module.0) })
6069 }
6170
62− unsafe fn unregister(pdrv: &Opaque<Self::RegType>) {
63− // SAFETY: `pdrv` is guaranteed to be a valid `RegType`.
71+ unsafe fn unregister(pdrv: &Opaque<Self::DriverType>) {
72+ // SAFETY: `pdrv` is guaranteed to be a valid `DriverType`.
6473 unsafe { bindings::platform_driver_unregister(pdrv.get()) };
6574 }
6675 }
@@ -92,9 +101,9 @@ impl<T: Driver + 'static> Adapter<T> { · 25 unmodified lines
92101 // SAFETY: `remove_callback` is only ever called after a successful call to
93102 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
94103 // and stored a `Pin<KBox<T>>`.
95− let data = unsafe { pdev.as_ref().drvdata_obtain::<T>() };
104+ let data = unsafe { pdev.as_ref().drvdata_borrow::<T>() };
96105
97− T::unbind(pdev, data.as_ref());
106+ T::unbind(pdev, data);
98107 }
99108 }
100109
rust/kernel/usb.rs+18−9
@@ -27,13 +27,22 @@ use core::{ · 26 unmodified lines
2727 /// An adapter for the registration of USB drivers.
2828 pub struct Adapter<T: Driver>(T);
2929
30−// SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if
30+// SAFETY:
31+// - `bindings::usb_driver` is a C type declared as `repr(C)`.
32+// - `T` is the type of the driver's device private data.
33+// - `struct usb_driver` embeds a `struct device_driver`.
34+// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
35+unsafe impl<T: Driver + 'static> driver::DriverLayout for Adapter<T> {
36+ type DriverType = bindings::usb_driver;
37+ type DriverData = T;
38+ const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
39+}
40+
41+// SAFETY: A call to `unregister` for a given instance of `DriverType` is guaranteed to be valid if
3142 // a preceding call to `register` has been successful.
3243 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
33− type RegType = bindings::usb_driver;
34−
3544 unsafe fn register(
36− udrv: &Opaque<Self::RegType>,
45+ udrv: &Opaque<Self::DriverType>,
3746 name: &'static CStr,
3847 module: &'static ThisModule,
3948 ) -> Result {
@@ -45,14 +54,14 @@ unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { · 5 unmodified lines
4554 (*udrv.get()).id_table = T::ID_TABLE.as_ptr();
4655 }
4756
48− // SAFETY: `udrv` is guaranteed to be a valid `RegType`.
57+ // SAFETY: `udrv` is guaranteed to be a valid `DriverType`.
4958 to_result(unsafe {
5059 bindings::usb_register_driver(udrv.get(), module.0, name.as_char_ptr())
5160 })
5261 }
5362
54− unsafe fn unregister(udrv: &Opaque<Self::RegType>) {
55− // SAFETY: `udrv` is guaranteed to be a valid `RegType`.
63+ unsafe fn unregister(udrv: &Opaque<Self::DriverType>) {
64+ // SAFETY: `udrv` is guaranteed to be a valid `DriverType`.
5665 unsafe { bindings::usb_deregister(udrv.get()) };
5766 }
5867 }
@@ -94,9 +103,9 @@ impl<T: Driver + 'static> Adapter<T> { · 35 unmodified lines
94103 // SAFETY: `disconnect_callback` is only ever called after a successful call to
95104 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
96105 // and stored a `Pin<KBox<T>>`.
97− let data = unsafe { dev.drvdata_obtain::<T>() };
106+ let data = unsafe { dev.drvdata_borrow::<T>() };
98107
99− T::disconnect(intf, data.as_ref());
108+ T::disconnect(intf, data);
100109 }
101110 }
102111