From: Alice Ryhl Date: Fri, 22 Aug 2025 08:42:35 +0000 (+0000) Subject: rust: miscdevice: Provide additional abstractions for iov_iter and kiocb structures X-Git-Tag: v6.18-rc1~74^2~51^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=39c2745b37dac18c6604083f26caea3fd7e4c50b;p=thirdparty%2Fkernel%2Flinux.git rust: miscdevice: Provide additional abstractions for iov_iter and kiocb structures These will be used for the read_iter() and write_iter() callbacks, which are now the preferred back-ends for when a user operates on a char device with read() and write() respectively. Co-developed-by: Lee Jones Signed-off-by: Lee Jones Reviewed-by: Andreas Hindborg Signed-off-by: Alice Ryhl Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20250822-iov-iter-v5-4-6ce4819c2977@google.com --- diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs index 6373fe183b27..35630fc63875 100644 --- a/rust/kernel/miscdevice.rs +++ b/rust/kernel/miscdevice.rs @@ -13,7 +13,8 @@ use crate::{ device::Device, error::{to_result, Error, Result, VTABLE_DEFAULT_ERROR}, ffi::{c_int, c_long, c_uint, c_ulong}, - fs::File, + fs::{File, Kiocb}, + iov::{IovIterDest, IovIterSource}, mm::virt::VmaNew, prelude::*, seq_file::SeqFile, @@ -141,6 +142,16 @@ pub trait MiscDevice: Sized { build_error!(VTABLE_DEFAULT_ERROR) } + /// Read from this miscdevice. + fn read_iter(_kiocb: Kiocb<'_, Self::Ptr>, _iov: &mut IovIterDest<'_>) -> Result { + build_error!(VTABLE_DEFAULT_ERROR) + } + + /// Write to this miscdevice. + fn write_iter(_kiocb: Kiocb<'_, Self::Ptr>, _iov: &mut IovIterSource<'_>) -> Result { + build_error!(VTABLE_DEFAULT_ERROR) + } + /// Handler for ioctls. /// /// The `cmd` argument is usually manipulated using the utilities in [`kernel::ioctl`]. @@ -245,6 +256,46 @@ impl MiscdeviceVTable { 0 } + /// # Safety + /// + /// `kiocb` must be correspond to a valid file that is associated with a + /// `MiscDeviceRegistration`. `iter` must be a valid `struct iov_iter` for writing. + unsafe extern "C" fn read_iter( + kiocb: *mut bindings::kiocb, + iter: *mut bindings::iov_iter, + ) -> isize { + // SAFETY: The caller provides a valid `struct kiocb` associated with a + // `MiscDeviceRegistration` file. + let kiocb = unsafe { Kiocb::from_raw(kiocb) }; + // SAFETY: This is a valid `struct iov_iter` for writing. + let iov = unsafe { IovIterDest::from_raw(iter) }; + + match T::read_iter(kiocb, iov) { + Ok(res) => res as isize, + Err(err) => err.to_errno() as isize, + } + } + + /// # Safety + /// + /// `kiocb` must be correspond to a valid file that is associated with a + /// `MiscDeviceRegistration`. `iter` must be a valid `struct iov_iter` for writing. + unsafe extern "C" fn write_iter( + kiocb: *mut bindings::kiocb, + iter: *mut bindings::iov_iter, + ) -> isize { + // SAFETY: The caller provides a valid `struct kiocb` associated with a + // `MiscDeviceRegistration` file. + let kiocb = unsafe { Kiocb::from_raw(kiocb) }; + // SAFETY: This is a valid `struct iov_iter` for reading. + let iov = unsafe { IovIterSource::from_raw(iter) }; + + match T::write_iter(kiocb, iov) { + Ok(res) => res as isize, + Err(err) => err.to_errno() as isize, + } + } + /// # Safety /// /// `file` must be a valid file that is associated with a `MiscDeviceRegistration`. @@ -341,6 +392,16 @@ impl MiscdeviceVTable { open: Some(Self::open), release: Some(Self::release), mmap: if T::HAS_MMAP { Some(Self::mmap) } else { None }, + read_iter: if T::HAS_READ_ITER { + Some(Self::read_iter) + } else { + None + }, + write_iter: if T::HAS_WRITE_ITER { + Some(Self::write_iter) + } else { + None + }, unlocked_ioctl: if T::HAS_IOCTL { Some(Self::ioctl) } else {