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

+209 -74
+2
drivers/base/dd.c
··· 548 static void device_unbind_cleanup(struct device *dev) 549 { 550 devres_release_all(dev); 551 arch_teardown_dma_ops(dev); 552 kfree(dev->dma_range_map); 553 dev->dma_range_map = NULL;
··· 548 static void device_unbind_cleanup(struct device *dev) 549 { 550 devres_release_all(dev); 551 + if (dev->driver->p_cb.post_unbind_rust) 552 + dev->driver->p_cb.post_unbind_rust(dev); 553 arch_teardown_dma_ops(dev); 554 kfree(dev->dma_range_map); 555 dev->dma_range_map = NULL;
+9
include/linux/device/driver.h
··· 85 * uevent. 86 * @p: Driver core's private data, no one other than the driver 87 * core can touch this. 88 * 89 * The device driver-model tracks all of the drivers known to the system. 90 * The main reason for this tracking is to enable the driver core to match ··· 121 void (*coredump) (struct device *dev); 122 123 struct driver_private *p; 124 }; 125 126
··· 85 * uevent. 86 * @p: Driver core's private data, no one other than the driver 87 * 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. 90 * 91 * The device driver-model tracks all of the drivers known to the system. 92 * The main reason for this tracking is to enable the driver core to match ··· 119 void (*coredump) (struct device *dev); 120 121 struct driver_private *p; 122 + struct { 123 + /* 124 + * Called after remove() and after all devres entries have been 125 + * processed. This is a Rust only callback. 126 + */ 127 + void (*post_unbind_rust)(struct device *dev); 128 + } p_cb; 129 }; 130 131
+33 -8
rust/kernel/auxiliary.rs
··· 23 /// An adapter for the registration of auxiliary drivers. 24 pub struct Adapter<T: Driver>(T); 25 26 - // SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if 27 // a preceding call to `register` has been successful. 28 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { 29 - type RegType = bindings::auxiliary_driver; 30 - 31 unsafe fn register( 32 - adrv: &Opaque<Self::RegType>, 33 name: &'static CStr, 34 module: &'static ThisModule, 35 ) -> Result { ··· 50 (*adrv.get()).id_table = T::ID_TABLE.as_ptr(); 51 } 52 53 - // SAFETY: `adrv` is guaranteed to be a valid `RegType`. 54 to_result(unsafe { 55 bindings::__auxiliary_driver_register(adrv.get(), module.0, name.as_char_ptr()) 56 }) 57 } 58 59 - unsafe fn unregister(adrv: &Opaque<Self::RegType>) { 60 - // SAFETY: `adrv` is guaranteed to be a valid `RegType`. 61 unsafe { bindings::auxiliary_driver_unregister(adrv.get()) } 62 } 63 } ··· 96 // SAFETY: `remove_callback` is only ever called after a successful call to 97 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 98 // and stored a `Pin<KBox<T>>`. 99 - drop(unsafe { adev.as_ref().drvdata_obtain::<T>() }); 100 } 101 } 102 ··· 198 /// 199 /// Called when an auxiliary device is matches a corresponding driver. 200 fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> impl PinInit<Self, Error>; 201 } 202 203 /// The auxiliary device representation.
··· 23 /// An adapter for the registration of auxiliary drivers. 24 pub struct Adapter<T: Driver>(T); 25 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 38 // a preceding call to `register` has been successful. 39 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { 40 unsafe fn register( 41 + adrv: &Opaque<Self::DriverType>, 42 name: &'static CStr, 43 module: &'static ThisModule, 44 ) -> Result { ··· 41 (*adrv.get()).id_table = T::ID_TABLE.as_ptr(); 42 } 43 44 + // SAFETY: `adrv` is guaranteed to be a valid `DriverType`. 45 to_result(unsafe { 46 bindings::__auxiliary_driver_register(adrv.get(), module.0, name.as_char_ptr()) 47 }) 48 } 49 50 + unsafe fn unregister(adrv: &Opaque<Self::DriverType>) { 51 + // SAFETY: `adrv` is guaranteed to be a valid `DriverType`. 52 unsafe { bindings::auxiliary_driver_unregister(adrv.get()) } 53 } 54 } ··· 87 // SAFETY: `remove_callback` is only ever called after a successful call to 88 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 89 // and stored a `Pin<KBox<T>>`. 90 + let data = unsafe { adev.as_ref().drvdata_borrow::<T>() }; 91 + 92 + T::unbind(adev, data); 93 } 94 } 95 ··· 187 /// 188 /// Called when an auxiliary device is matches a corresponding driver. 189 fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> impl PinInit<Self, Error>; 190 + 191 + /// Auxiliary driver unbind. 192 + /// 193 + /// Called when a [`Device`] is unbound from its bound [`Driver`]. Implementing this callback 194 + /// is optional. 195 + /// 196 + /// This callback serves as a place for drivers to perform teardown operations that require a 197 + /// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O 198 + /// operations to gracefully tear down the device. 199 + /// 200 + /// Otherwise, release operations for driver resources should be performed in `Self::drop`. 201 + fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) { 202 + let _ = (dev, this); 203 + } 204 } 205 206 /// The auxiliary device representation.
+11 -9
rust/kernel/device.rs
··· 232 /// 233 /// # Safety 234 /// 235 - /// - Must only be called once after a preceding call to [`Device::set_drvdata`]. 236 /// - The type `T` must match the type of the `ForeignOwnable` previously stored by 237 /// [`Device::set_drvdata`]. 238 - pub unsafe fn drvdata_obtain<T: 'static>(&self) -> Pin<KBox<T>> { 239 // SAFETY: By the type invariants, `self.as_raw()` is a valid pointer to a `struct device`. 240 let ptr = unsafe { bindings::dev_get_drvdata(self.as_raw()) }; 241 242 // SAFETY: By the type invariants, `self.as_raw()` is a valid pointer to a `struct device`. 243 unsafe { bindings::dev_set_drvdata(self.as_raw(), core::ptr::null_mut()) }; 244 245 // SAFETY: 246 - // - By the safety requirements of this function, `ptr` comes from a previous call to 247 - // `into_foreign()`. 248 // - `dev_get_drvdata()` guarantees to return the same pointer given to `dev_set_drvdata()` 249 // in `into_foreign()`. 250 - unsafe { Pin::<KBox<T>>::from_foreign(ptr.cast()) } 251 } 252 253 /// Borrow the driver's private data bound to this [`Device`]. 254 /// 255 /// # Safety 256 /// 257 - /// - Must only be called after a preceding call to [`Device::set_drvdata`] and before 258 - /// [`Device::drvdata_obtain`]. 259 /// - The type `T` must match the type of the `ForeignOwnable` previously stored by 260 /// [`Device::set_drvdata`]. 261 pub unsafe fn drvdata_borrow<T: 'static>(&self) -> Pin<&T> { ··· 273 /// # Safety 274 /// 275 /// - Must only be called after a preceding call to [`Device::set_drvdata`] and before 276 - /// [`Device::drvdata_obtain`]. 277 /// - The type `T` must match the type of the `ForeignOwnable` previously stored by 278 /// [`Device::set_drvdata`]. 279 unsafe fn drvdata_unchecked<T: 'static>(&self) -> Pin<&T> { ··· 322 323 // SAFETY: 324 // - The above check of `dev_get_drvdata()` guarantees that we are called after 325 - // `set_drvdata()` and before `drvdata_obtain()`. 326 // - We've just checked that the type of the driver's private data is in fact `T`. 327 Ok(unsafe { self.drvdata_unchecked() }) 328 }
··· 232 /// 233 /// # Safety 234 /// 235 /// - The type `T` must match the type of the `ForeignOwnable` previously stored by 236 /// [`Device::set_drvdata`]. 237 + pub(crate) unsafe fn drvdata_obtain<T: 'static>(&self) -> Option<Pin<KBox<T>>> { 238 // SAFETY: By the type invariants, `self.as_raw()` is a valid pointer to a `struct device`. 239 let ptr = unsafe { bindings::dev_get_drvdata(self.as_raw()) }; 240 241 // SAFETY: By the type invariants, `self.as_raw()` is a valid pointer to a `struct device`. 242 unsafe { bindings::dev_set_drvdata(self.as_raw(), core::ptr::null_mut()) }; 243 244 + if ptr.is_null() { 245 + return None; 246 + } 247 + 248 // SAFETY: 249 + // - If `ptr` is not NULL, it comes from a previous call to `into_foreign()`. 250 // - `dev_get_drvdata()` guarantees to return the same pointer given to `dev_set_drvdata()` 251 // in `into_foreign()`. 252 + Some(unsafe { Pin::<KBox<T>>::from_foreign(ptr.cast()) }) 253 } 254 255 /// Borrow the driver's private data bound to this [`Device`]. 256 /// 257 /// # Safety 258 /// 259 + /// - Must only be called after a preceding call to [`Device::set_drvdata`] and before the 260 + /// device is fully unbound. 261 /// - The type `T` must match the type of the `ForeignOwnable` previously stored by 262 /// [`Device::set_drvdata`]. 263 pub unsafe fn drvdata_borrow<T: 'static>(&self) -> Pin<&T> { ··· 271 /// # Safety 272 /// 273 /// - Must only be called after a preceding call to [`Device::set_drvdata`] and before 274 + /// the device is fully unbound. 275 /// - The type `T` must match the type of the `ForeignOwnable` previously stored by 276 /// [`Device::set_drvdata`]. 277 unsafe fn drvdata_unchecked<T: 'static>(&self) -> Pin<&T> { ··· 320 321 // SAFETY: 322 // - The above check of `dev_get_drvdata()` guarantees that we are called after 323 + // `set_drvdata()`. 324 // - We've just checked that the type of the driver's private data is in fact `T`. 325 Ok(unsafe { self.drvdata_unchecked() }) 326 }
+70 -16
rust/kernel/driver.rs
··· 99 use core::pin::Pin; 100 use pin_init::{pin_data, pinned_drop, PinInit}; 101 102 /// The [`RegistrationOps`] trait serves as generic interface for subsystems (e.g., PCI, Platform, 103 /// Amba, etc.) to provide the corresponding subsystem specific implementation to register / 104 - /// unregister a driver of the particular type (`RegType`). 105 /// 106 - /// For instance, the PCI subsystem would set `RegType` to `bindings::pci_driver` and call 107 /// `bindings::__pci_register_driver` from `RegistrationOps::register` and 108 /// `bindings::pci_unregister_driver` from `RegistrationOps::unregister`. 109 /// 110 /// # Safety 111 /// 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 - 119 /// Registers a driver. 120 /// 121 /// # Safety ··· 143 /// On success, `reg` must remain pinned and valid until the matching call to 144 /// [`RegistrationOps::unregister`]. 145 unsafe fn register( 146 - reg: &Opaque<Self::RegType>, 147 name: &'static CStr, 148 module: &'static ThisModule, 149 ) -> Result; ··· 154 /// 155 /// Must only be called after a preceding successful call to [`RegistrationOps::register`] for 156 /// the same `reg`. 157 - unsafe fn unregister(reg: &Opaque<Self::RegType>); 158 } 159 160 /// A [`Registration`] is a generic type that represents the registration of some driver type (e.g. ··· 166 #[pin_data(PinnedDrop)] 167 pub struct Registration<T: RegistrationOps> { 168 #[pin] 169 - reg: Opaque<T::RegType>, 170 } 171 172 // SAFETY: `Registration` has no fields or methods accessible via `&Registration`, so it is safe to ··· 177 // any thread, so `Registration` is `Send`. 178 unsafe impl<T: RegistrationOps> Send for Registration<T> {} 179 180 - impl<T: RegistrationOps> Registration<T> { 181 /// Creates a new instance of the registration object. 182 pub fn new(name: &'static CStr, module: &'static ThisModule) -> impl PinInit<Self, Error> { 183 try_pin_init!(Self { 184 - reg <- Opaque::try_ffi_init(|ptr: *mut T::RegType| { 185 // SAFETY: `try_ffi_init` guarantees that `ptr` is valid for write. 186 - unsafe { ptr.write(T::RegType::default()) }; 187 188 // SAFETY: `try_ffi_init` guarantees that `ptr` is valid for write, and it has 189 // just been initialised above, so it's also valid for read. 190 - let drv = unsafe { &*(ptr as *const Opaque<T::RegType>) }; 191 192 // SAFETY: `drv` is guaranteed to be pinned until `T::unregister`. 193 unsafe { T::register(drv, name, module) }
··· 99 use core::pin::Pin; 100 use pin_init::{pin_data, pinned_drop, PinInit}; 101 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 + 126 /// The [`RegistrationOps`] trait serves as generic interface for subsystems (e.g., PCI, Platform, 127 /// Amba, etc.) to provide the corresponding subsystem specific implementation to register / 128 + /// unregister a driver of the particular type (`DriverType`). 129 /// 130 + /// For instance, the PCI subsystem would set `DriverType` to `bindings::pci_driver` and call 131 /// `bindings::__pci_register_driver` from `RegistrationOps::register` and 132 /// `bindings::pci_unregister_driver` from `RegistrationOps::unregister`. 133 /// 134 /// # Safety 135 /// 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 { 139 /// Registers a driver. 140 /// 141 /// # Safety ··· 123 /// On success, `reg` must remain pinned and valid until the matching call to 124 /// [`RegistrationOps::unregister`]. 125 unsafe fn register( 126 + reg: &Opaque<Self::DriverType>, 127 name: &'static CStr, 128 module: &'static ThisModule, 129 ) -> Result; ··· 134 /// 135 /// Must only be called after a preceding successful call to [`RegistrationOps::register`] for 136 /// the same `reg`. 137 + unsafe fn unregister(reg: &Opaque<Self::DriverType>); 138 } 139 140 /// A [`Registration`] is a generic type that represents the registration of some driver type (e.g. ··· 146 #[pin_data(PinnedDrop)] 147 pub struct Registration<T: RegistrationOps> { 148 #[pin] 149 + reg: Opaque<T::DriverType>, 150 } 151 152 // SAFETY: `Registration` has no fields or methods accessible via `&Registration`, so it is safe to ··· 157 // any thread, so `Registration` is `Send`. 158 unsafe impl<T: RegistrationOps> Send for Registration<T> {} 159 160 + impl<T: RegistrationOps + 'static> Registration<T> { 161 + extern "C" fn post_unbind_callback(dev: *mut bindings::device) { 162 + // SAFETY: The driver core only ever calls the post unbind callback with a valid pointer to 163 + // a `struct device`. 164 + // 165 + // INVARIANT: `dev` is valid for the duration of the `post_unbind_callback()`. 166 + let dev = unsafe { &*dev.cast::<device::Device<device::CoreInternal>>() }; 167 + 168 + // `remove()` and all devres callbacks have been completed at this point, hence drop the 169 + // driver's device private data. 170 + // 171 + // SAFETY: By the safety requirements of the `Driver` trait, `T::DriverData` is the 172 + // driver's device private data type. 173 + drop(unsafe { dev.drvdata_obtain::<T::DriverData>() }); 174 + } 175 + 176 + /// Attach generic `struct device_driver` callbacks. 177 + fn callbacks_attach(drv: &Opaque<T::DriverType>) { 178 + let ptr = drv.get().cast::<u8>(); 179 + 180 + // SAFETY: 181 + // - `drv.get()` yields a valid pointer to `Self::DriverType`. 182 + // - Adding `DEVICE_DRIVER_OFFSET` yields the address of the embedded `struct device_driver` 183 + // as guaranteed by the safety requirements of the `Driver` trait. 184 + let base = unsafe { ptr.add(T::DEVICE_DRIVER_OFFSET) }; 185 + 186 + // CAST: `base` points to the offset of the embedded `struct device_driver`. 187 + let base = base.cast::<bindings::device_driver>(); 188 + 189 + // SAFETY: It is safe to set the fields of `struct device_driver` on initialization. 190 + unsafe { (*base).p_cb.post_unbind_rust = Some(Self::post_unbind_callback) }; 191 + } 192 + 193 /// Creates a new instance of the registration object. 194 pub fn new(name: &'static CStr, module: &'static ThisModule) -> impl PinInit<Self, Error> { 195 try_pin_init!(Self { 196 + reg <- Opaque::try_ffi_init(|ptr: *mut T::DriverType| { 197 // SAFETY: `try_ffi_init` guarantees that `ptr` is valid for write. 198 + unsafe { ptr.write(T::DriverType::default()) }; 199 200 // SAFETY: `try_ffi_init` guarantees that `ptr` is valid for write, and it has 201 // just been initialised above, so it's also valid for read. 202 + let drv = unsafe { &*(ptr as *const Opaque<T::DriverType>) }; 203 + 204 + Self::callbacks_attach(drv); 205 206 // SAFETY: `drv` is guaranteed to be pinned until `T::unregister`. 207 unsafe { T::register(drv, name, module) }
+20 -11
rust/kernel/i2c.rs
··· 92 /// An adapter for the registration of I2C drivers. 93 pub struct Adapter<T: Driver>(T); 94 95 - // SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if 96 // a preceding call to `register` has been successful. 97 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { 98 - type RegType = bindings::i2c_driver; 99 - 100 unsafe fn register( 101 - idrv: &Opaque<Self::RegType>, 102 name: &'static CStr, 103 module: &'static ThisModule, 104 ) -> Result { ··· 142 (*idrv.get()).driver.acpi_match_table = acpi_table; 143 } 144 145 - // SAFETY: `idrv` is guaranteed to be a valid `RegType`. 146 to_result(unsafe { bindings::i2c_register_driver(module.0, idrv.get()) }) 147 } 148 149 - unsafe fn unregister(idrv: &Opaque<Self::RegType>) { 150 - // SAFETY: `idrv` is guaranteed to be a valid `RegType`. 151 unsafe { bindings::i2c_del_driver(idrv.get()) } 152 } 153 } ··· 178 // SAFETY: `remove_callback` is only ever called after a successful call to 179 // `probe_callback`, hence it's guaranteed that `I2cClient::set_drvdata()` has been called 180 // and stored a `Pin<KBox<T>>`. 181 - let data = unsafe { idev.as_ref().drvdata_obtain::<T>() }; 182 183 - T::unbind(idev, data.as_ref()); 184 } 185 186 extern "C" fn shutdown_callback(idev: *mut bindings::i2c_client) { ··· 190 // SAFETY: `shutdown_callback` is only ever called after a successful call to 191 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 192 // and stored a `Pin<KBox<T>>`. 193 - let data = unsafe { idev.as_ref().drvdata_obtain::<T>() }; 194 195 - T::shutdown(idev, data.as_ref()); 196 } 197 198 /// The [`i2c::IdTable`] of the corresponding driver.
··· 92 /// An adapter for the registration of I2C drivers. 93 pub struct Adapter<T: Driver>(T); 94 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 107 // a preceding call to `register` has been successful. 108 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { 109 unsafe fn register( 110 + idrv: &Opaque<Self::DriverType>, 111 name: &'static CStr, 112 module: &'static ThisModule, 113 ) -> Result { ··· 133 (*idrv.get()).driver.acpi_match_table = acpi_table; 134 } 135 136 + // SAFETY: `idrv` is guaranteed to be a valid `DriverType`. 137 to_result(unsafe { bindings::i2c_register_driver(module.0, idrv.get()) }) 138 } 139 140 + unsafe fn unregister(idrv: &Opaque<Self::DriverType>) { 141 + // SAFETY: `idrv` is guaranteed to be a valid `DriverType`. 142 unsafe { bindings::i2c_del_driver(idrv.get()) } 143 } 144 } ··· 169 // SAFETY: `remove_callback` is only ever called after a successful call to 170 // `probe_callback`, hence it's guaranteed that `I2cClient::set_drvdata()` has been called 171 // and stored a `Pin<KBox<T>>`. 172 + let data = unsafe { idev.as_ref().drvdata_borrow::<T>() }; 173 174 + T::unbind(idev, data); 175 } 176 177 extern "C" fn shutdown_callback(idev: *mut bindings::i2c_client) { ··· 181 // SAFETY: `shutdown_callback` is only ever called after a successful call to 182 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 183 // and stored a `Pin<KBox<T>>`. 184 + let data = unsafe { idev.as_ref().drvdata_borrow::<T>() }; 185 186 + T::shutdown(idev, data); 187 } 188 189 /// The [`i2c::IdTable`] of the corresponding driver.
+6 -3
rust/kernel/io.rs
··· 142 /// Bound checks are performed on compile time, hence if the offset is not known at compile 143 /// time, the build will fail. 144 $(#[$attr])* 145 - #[inline] 146 pub fn $name(&self, offset: usize) -> $type_name { 147 let addr = self.io_addr_assert::<$type_name>(offset); 148 ··· 172 /// Bound checks are performed on compile time, hence if the offset is not known at compile 173 /// time, the build will fail. 174 $(#[$attr])* 175 - #[inline] 176 pub fn $name(&self, value: $type_name, offset: usize) { 177 let addr = self.io_addr_assert::<$type_name>(offset); 178 ··· 241 self.addr().checked_add(offset).ok_or(EINVAL) 242 } 243 244 - #[inline] 245 fn io_addr_assert<U>(&self, offset: usize) -> usize { 246 build_assert!(Self::offset_valid::<U>(offset, SIZE)); 247
··· 142 /// Bound checks are performed on compile time, hence if the offset is not known at compile 143 /// time, the build will fail. 144 $(#[$attr])* 145 + // Always inline to optimize out error path of `io_addr_assert`. 146 + #[inline(always)] 147 pub fn $name(&self, offset: usize) -> $type_name { 148 let addr = self.io_addr_assert::<$type_name>(offset); 149 ··· 171 /// Bound checks are performed on compile time, hence if the offset is not known at compile 172 /// time, the build will fail. 173 $(#[$attr])* 174 + // Always inline to optimize out error path of `io_addr_assert`. 175 + #[inline(always)] 176 pub fn $name(&self, value: $type_name, offset: usize) { 177 let addr = self.io_addr_assert::<$type_name>(offset); 178 ··· 239 self.addr().checked_add(offset).ok_or(EINVAL) 240 } 241 242 + // Always inline to optimize out error path of `build_assert`. 243 + #[inline(always)] 244 fn io_addr_assert<U>(&self, offset: usize) -> usize { 245 build_assert!(Self::offset_valid::<U>(offset, SIZE)); 246
+2
rust/kernel/io/resource.rs
··· 226 /// Resource represents a memory region that must be ioremaped using `ioremap_np`. 227 pub const IORESOURCE_MEM_NONPOSTED: Flags = Flags::new(bindings::IORESOURCE_MEM_NONPOSTED); 228 229 const fn new(value: u32) -> Self { 230 crate::build_assert!(value as u64 <= c_ulong::MAX as u64); 231 Flags(value as c_ulong)
··· 226 /// Resource represents a memory region that must be ioremaped using `ioremap_np`. 227 pub const IORESOURCE_MEM_NONPOSTED: Flags = Flags::new(bindings::IORESOURCE_MEM_NONPOSTED); 228 229 + // Always inline to optimize out error path of `build_assert`. 230 + #[inline(always)] 231 const fn new(value: u32) -> Self { 232 crate::build_assert!(value as u64 <= c_ulong::MAX as u64); 233 Flags(value as c_ulong)
+2
rust/kernel/irq/flags.rs
··· 96 self.0 97 } 98 99 const fn new(value: u32) -> Self { 100 build_assert!(value as u64 <= c_ulong::MAX as u64); 101 Self(value as c_ulong)
··· 96 self.0 97 } 98 99 + // Always inline to optimize out error path of `build_assert`. 100 + #[inline(always)] 101 const fn new(value: u32) -> Self { 102 build_assert!(value as u64 <= c_ulong::MAX as u64); 103 Self(value as c_ulong)
+18 -9
rust/kernel/pci.rs
··· 50 /// An adapter for the registration of PCI drivers. 51 pub struct Adapter<T: Driver>(T); 52 53 - // SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if 54 // a preceding call to `register` has been successful. 55 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { 56 - type RegType = bindings::pci_driver; 57 - 58 unsafe fn register( 59 - pdrv: &Opaque<Self::RegType>, 60 name: &'static CStr, 61 module: &'static ThisModule, 62 ) -> Result { ··· 77 (*pdrv.get()).id_table = T::ID_TABLE.as_ptr(); 78 } 79 80 - // SAFETY: `pdrv` is guaranteed to be a valid `RegType`. 81 to_result(unsafe { 82 bindings::__pci_register_driver(pdrv.get(), module.0, name.as_char_ptr()) 83 }) 84 } 85 86 - unsafe fn unregister(pdrv: &Opaque<Self::RegType>) { 87 - // SAFETY: `pdrv` is guaranteed to be a valid `RegType`. 88 unsafe { bindings::pci_unregister_driver(pdrv.get()) } 89 } 90 } ··· 123 // SAFETY: `remove_callback` is only ever called after a successful call to 124 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 125 // and stored a `Pin<KBox<T>>`. 126 - let data = unsafe { pdev.as_ref().drvdata_obtain::<T>() }; 127 128 - T::unbind(pdev, data.as_ref()); 129 } 130 } 131
··· 50 /// An adapter for the registration of PCI drivers. 51 pub struct Adapter<T: Driver>(T); 52 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 65 // a preceding call to `register` has been successful. 66 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { 67 unsafe fn register( 68 + pdrv: &Opaque<Self::DriverType>, 69 name: &'static CStr, 70 module: &'static ThisModule, 71 ) -> Result { ··· 68 (*pdrv.get()).id_table = T::ID_TABLE.as_ptr(); 69 } 70 71 + // SAFETY: `pdrv` is guaranteed to be a valid `DriverType`. 72 to_result(unsafe { 73 bindings::__pci_register_driver(pdrv.get(), module.0, name.as_char_ptr()) 74 }) 75 } 76 77 + unsafe fn unregister(pdrv: &Opaque<Self::DriverType>) { 78 + // SAFETY: `pdrv` is guaranteed to be a valid `DriverType`. 79 unsafe { bindings::pci_unregister_driver(pdrv.get()) } 80 } 81 } ··· 114 // SAFETY: `remove_callback` is only ever called after a successful call to 115 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 116 // and stored a `Pin<KBox<T>>`. 117 + let data = unsafe { pdev.as_ref().drvdata_borrow::<T>() }; 118 119 + T::unbind(pdev, data); 120 } 121 } 122
+18 -9
rust/kernel/platform.rs
··· 26 /// An adapter for the registration of platform drivers. 27 pub struct Adapter<T: Driver>(T); 28 29 - // SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if 30 // a preceding call to `register` has been successful. 31 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { 32 - type RegType = bindings::platform_driver; 33 - 34 unsafe fn register( 35 - pdrv: &Opaque<Self::RegType>, 36 name: &'static CStr, 37 module: &'static ThisModule, 38 ) -> Result { ··· 64 (*pdrv.get()).driver.acpi_match_table = acpi_table; 65 } 66 67 - // SAFETY: `pdrv` is guaranteed to be a valid `RegType`. 68 to_result(unsafe { bindings::__platform_driver_register(pdrv.get(), module.0) }) 69 } 70 71 - unsafe fn unregister(pdrv: &Opaque<Self::RegType>) { 72 - // SAFETY: `pdrv` is guaranteed to be a valid `RegType`. 73 unsafe { bindings::platform_driver_unregister(pdrv.get()) }; 74 } 75 } ··· 101 // SAFETY: `remove_callback` is only ever called after a successful call to 102 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 103 // and stored a `Pin<KBox<T>>`. 104 - let data = unsafe { pdev.as_ref().drvdata_obtain::<T>() }; 105 106 - T::unbind(pdev, data.as_ref()); 107 } 108 } 109
··· 26 /// An adapter for the registration of platform drivers. 27 pub struct Adapter<T: Driver>(T); 28 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 41 // a preceding call to `register` has been successful. 42 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { 43 unsafe fn register( 44 + pdrv: &Opaque<Self::DriverType>, 45 name: &'static CStr, 46 module: &'static ThisModule, 47 ) -> Result { ··· 55 (*pdrv.get()).driver.acpi_match_table = acpi_table; 56 } 57 58 + // SAFETY: `pdrv` is guaranteed to be a valid `DriverType`. 59 to_result(unsafe { bindings::__platform_driver_register(pdrv.get(), module.0) }) 60 } 61 62 + unsafe fn unregister(pdrv: &Opaque<Self::DriverType>) { 63 + // SAFETY: `pdrv` is guaranteed to be a valid `DriverType`. 64 unsafe { bindings::platform_driver_unregister(pdrv.get()) }; 65 } 66 } ··· 92 // SAFETY: `remove_callback` is only ever called after a successful call to 93 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 94 // and stored a `Pin<KBox<T>>`. 95 + let data = unsafe { pdev.as_ref().drvdata_borrow::<T>() }; 96 97 + T::unbind(pdev, data); 98 } 99 } 100
+18 -9
rust/kernel/usb.rs
··· 27 /// An adapter for the registration of USB drivers. 28 pub struct Adapter<T: Driver>(T); 29 30 - // SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if 31 // a preceding call to `register` has been successful. 32 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { 33 - type RegType = bindings::usb_driver; 34 - 35 unsafe fn register( 36 - udrv: &Opaque<Self::RegType>, 37 name: &'static CStr, 38 module: &'static ThisModule, 39 ) -> Result { ··· 54 (*udrv.get()).id_table = T::ID_TABLE.as_ptr(); 55 } 56 57 - // SAFETY: `udrv` is guaranteed to be a valid `RegType`. 58 to_result(unsafe { 59 bindings::usb_register_driver(udrv.get(), module.0, name.as_char_ptr()) 60 }) 61 } 62 63 - unsafe fn unregister(udrv: &Opaque<Self::RegType>) { 64 - // SAFETY: `udrv` is guaranteed to be a valid `RegType`. 65 unsafe { bindings::usb_deregister(udrv.get()) }; 66 } 67 } ··· 103 // SAFETY: `disconnect_callback` is only ever called after a successful call to 104 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 105 // and stored a `Pin<KBox<T>>`. 106 - let data = unsafe { dev.drvdata_obtain::<T>() }; 107 108 - T::disconnect(intf, data.as_ref()); 109 } 110 } 111
··· 27 /// An adapter for the registration of USB drivers. 28 pub struct Adapter<T: Driver>(T); 29 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 42 // a preceding call to `register` has been successful. 43 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { 44 unsafe fn register( 45 + udrv: &Opaque<Self::DriverType>, 46 name: &'static CStr, 47 module: &'static ThisModule, 48 ) -> Result { ··· 45 (*udrv.get()).id_table = T::ID_TABLE.as_ptr(); 46 } 47 48 + // SAFETY: `udrv` is guaranteed to be a valid `DriverType`. 49 to_result(unsafe { 50 bindings::usb_register_driver(udrv.get(), module.0, name.as_char_ptr()) 51 }) 52 } 53 54 + unsafe fn unregister(udrv: &Opaque<Self::DriverType>) { 55 + // SAFETY: `udrv` is guaranteed to be a valid `DriverType`. 56 unsafe { bindings::usb_deregister(udrv.get()) }; 57 } 58 } ··· 94 // SAFETY: `disconnect_callback` is only ever called after a successful call to 95 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 96 // and stored a `Pin<KBox<T>>`. 97 + let data = unsafe { dev.drvdata_borrow::<T>() }; 98 99 + T::disconnect(intf, data); 100 } 101 } 102