Message ID | 20241210-miscdevice-file-param-v3-1-b2a79b666dc5@google.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Additional miscdevice fops parameters | expand |
On Tue, 10 Dec 2024, Alice Ryhl wrote: > This allows fops to access information about the underlying struct file > for the miscdevice. For example, the Binder driver needs to inspect the > O_NONBLOCK flag inside the fops->ioctl() hook. > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > --- > rust/kernel/miscdevice.rs | 31 +++++++++++++++++++++++++------ > 1 file changed, 25 insertions(+), 6 deletions(-) Reviewed-by: Lee Jones <lee@kernel.org> > diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs > index 7e2a79b3ae26..0cb79676c139 100644 > --- a/rust/kernel/miscdevice.rs > +++ b/rust/kernel/miscdevice.rs > @@ -11,6 +11,7 @@ > use crate::{ > bindings, > error::{to_result, Error, Result, VTABLE_DEFAULT_ERROR}, > + fs::File, > prelude::*, > str::CStr, > types::{ForeignOwnable, Opaque}, > @@ -103,10 +104,10 @@ pub trait MiscDevice { > /// Called when the misc device is opened. > /// > /// The returned pointer will be stored as the private data for the file. > - fn open() -> Result<Self::Ptr>; > + fn open(_file: &File) -> Result<Self::Ptr>; > > /// Called when the misc device is released. > - fn release(device: Self::Ptr) { > + fn release(device: Self::Ptr, _file: &File) { > drop(device); > } > > @@ -117,6 +118,7 @@ fn release(device: Self::Ptr) { > /// [`kernel::ioctl`]: mod@crate::ioctl > fn ioctl( > _device: <Self::Ptr as ForeignOwnable>::Borrowed<'_>, > + _file: &File, > _cmd: u32, > _arg: usize, > ) -> Result<isize> { > @@ -133,6 +135,7 @@ fn ioctl( > #[cfg(CONFIG_COMPAT)] > fn compat_ioctl( > _device: <Self::Ptr as ForeignOwnable>::Borrowed<'_>, > + _file: &File, > _cmd: u32, > _arg: usize, > ) -> Result<isize> { > @@ -187,7 +190,10 @@ impl<T: MiscDevice> VtableHelper<T> { > return ret; > } > > - let ptr = match T::open() { > + // SAFETY: > + // * The file is valid for the duration of this call. > + // * There is no active fdget_pos region on the file on this thread. > + let ptr = match T::open(unsafe { File::from_raw_file(file) }) { > Ok(ptr) => ptr, > Err(err) => return err.to_errno(), > }; > @@ -211,7 +217,10 @@ impl<T: MiscDevice> VtableHelper<T> { > // SAFETY: The release call of a file owns the private data. > let ptr = unsafe { <T::Ptr as ForeignOwnable>::from_foreign(private) }; > > - T::release(ptr); > + // SAFETY: > + // * The file is valid for the duration of this call. > + // * There is no active fdget_pos region on the file on this thread. > + T::release(ptr, unsafe { File::from_raw_file(file) }); > > 0 > } > @@ -229,7 +238,12 @@ impl<T: MiscDevice> VtableHelper<T> { > // SAFETY: Ioctl calls can borrow the private data of the file. > let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; > > - match T::ioctl(device, cmd, arg as usize) { > + // SAFETY: > + // * The file is valid for the duration of this call. > + // * There is no active fdget_pos region on the file on this thread. > + let file = unsafe { File::from_raw_file(file) }; > + > + match T::ioctl(device, file, cmd, arg as usize) { > Ok(ret) => ret as c_long, > Err(err) => err.to_errno() as c_long, > } > @@ -249,7 +263,12 @@ impl<T: MiscDevice> VtableHelper<T> { > // SAFETY: Ioctl calls can borrow the private data of the file. > let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; > > - match T::compat_ioctl(device, cmd, arg as usize) { > + // SAFETY: > + // * The file is valid for the duration of this call. > + // * There is no active fdget_pos region on the file on this thread. > + let file = unsafe { File::from_raw_file(file) }; > + > + match T::compat_ioctl(device, file, cmd, arg as usize) { > Ok(ret) => ret as c_long, > Err(err) => err.to_errno() as c_long, > } > > -- > 2.47.1.613.gc27f4b7a9f-goog >
jn Wed, 11 Dec 2024, Lee Jones wrote: > On Tue, 10 Dec 2024, Alice Ryhl wrote: > > > This allows fops to access information about the underlying struct file > > for the miscdevice. For example, the Binder driver needs to inspect the > > O_NONBLOCK flag inside the fops->ioctl() hook. > > > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > > --- > > rust/kernel/miscdevice.rs | 31 +++++++++++++++++++++++++------ > > 1 file changed, 25 insertions(+), 6 deletions(-) > > Reviewed-by: Lee Jones <lee@kernel.org> Tested-by: Lee Jones <lee@kernel.org>
diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs index 7e2a79b3ae26..0cb79676c139 100644 --- a/rust/kernel/miscdevice.rs +++ b/rust/kernel/miscdevice.rs @@ -11,6 +11,7 @@ use crate::{ bindings, error::{to_result, Error, Result, VTABLE_DEFAULT_ERROR}, + fs::File, prelude::*, str::CStr, types::{ForeignOwnable, Opaque}, @@ -103,10 +104,10 @@ pub trait MiscDevice { /// Called when the misc device is opened. /// /// The returned pointer will be stored as the private data for the file. - fn open() -> Result<Self::Ptr>; + fn open(_file: &File) -> Result<Self::Ptr>; /// Called when the misc device is released. - fn release(device: Self::Ptr) { + fn release(device: Self::Ptr, _file: &File) { drop(device); } @@ -117,6 +118,7 @@ fn release(device: Self::Ptr) { /// [`kernel::ioctl`]: mod@crate::ioctl fn ioctl( _device: <Self::Ptr as ForeignOwnable>::Borrowed<'_>, + _file: &File, _cmd: u32, _arg: usize, ) -> Result<isize> { @@ -133,6 +135,7 @@ fn ioctl( #[cfg(CONFIG_COMPAT)] fn compat_ioctl( _device: <Self::Ptr as ForeignOwnable>::Borrowed<'_>, + _file: &File, _cmd: u32, _arg: usize, ) -> Result<isize> { @@ -187,7 +190,10 @@ impl<T: MiscDevice> VtableHelper<T> { return ret; } - let ptr = match T::open() { + // SAFETY: + // * The file is valid for the duration of this call. + // * There is no active fdget_pos region on the file on this thread. + let ptr = match T::open(unsafe { File::from_raw_file(file) }) { Ok(ptr) => ptr, Err(err) => return err.to_errno(), }; @@ -211,7 +217,10 @@ impl<T: MiscDevice> VtableHelper<T> { // SAFETY: The release call of a file owns the private data. let ptr = unsafe { <T::Ptr as ForeignOwnable>::from_foreign(private) }; - T::release(ptr); + // SAFETY: + // * The file is valid for the duration of this call. + // * There is no active fdget_pos region on the file on this thread. + T::release(ptr, unsafe { File::from_raw_file(file) }); 0 } @@ -229,7 +238,12 @@ impl<T: MiscDevice> VtableHelper<T> { // SAFETY: Ioctl calls can borrow the private data of the file. let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; - match T::ioctl(device, cmd, arg as usize) { + // SAFETY: + // * The file is valid for the duration of this call. + // * There is no active fdget_pos region on the file on this thread. + let file = unsafe { File::from_raw_file(file) }; + + match T::ioctl(device, file, cmd, arg as usize) { Ok(ret) => ret as c_long, Err(err) => err.to_errno() as c_long, } @@ -249,7 +263,12 @@ impl<T: MiscDevice> VtableHelper<T> { // SAFETY: Ioctl calls can borrow the private data of the file. let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; - match T::compat_ioctl(device, cmd, arg as usize) { + // SAFETY: + // * The file is valid for the duration of this call. + // * There is no active fdget_pos region on the file on this thread. + let file = unsafe { File::from_raw_file(file) }; + + match T::compat_ioctl(device, file, cmd, arg as usize) { Ok(ret) => ret as c_long, Err(err) => err.to_errno() as c_long, }
This allows fops to access information about the underlying struct file for the miscdevice. For example, the Binder driver needs to inspect the O_NONBLOCK flag inside the fops->ioctl() hook. Signed-off-by: Alice Ryhl <aliceryhl@google.com> --- rust/kernel/miscdevice.rs | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-)