UPSTREAM: rust: miscdevice: add mmap support
Add the ability to write a file_operations->mmap hook in Rust when using the miscdevice abstraction. The `vma` argument to the `mmap` hook uses the `VmaNew` type from the previous commit; this type provides the correct set of operations for a file_operations->mmap hook. Link: https://lkml.kernel.org/r/20250408-vma-v16-7-d8b446e885d9@google.com Signed-off-by: Alice Ryhl <aliceryhl@google.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Acked-by: Liam R. Howlett <Liam.Howlett@Oracle.com> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Reviewed-by: Gary Guo <gary@garyguo.net> Cc: Alex Gaynor <alex.gaynor@gmail.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Balbir Singh <balbirs@nvidia.com> Cc: Benno Lossin <benno.lossin@proton.me> Cc: Björn Roy Baron <bjorn3_gh@protonmail.com> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Jann Horn <jannh@google.com> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Miguel Ojeda <ojeda@kernel.org> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Trevor Gross <tmgross@umich.edu> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Bug: 429146594 (cherry picked from commit f8c78198816f04619da6eebfc5b67741bff56325) Change-Id: Ib8965aa5d000da6a97650eb04be61df3c21bd85a Signed-off-by: Alice Ryhl <aliceryhl@google.com>
This commit is contained in:
@@ -14,6 +14,7 @@ use crate::{
|
||||
error::{to_result, Error, Result, VTABLE_DEFAULT_ERROR},
|
||||
ffi::{c_int, c_long, c_uint, c_ulong, c_void},
|
||||
fs::{File, LocalFile},
|
||||
mm::virt::VmaNew,
|
||||
prelude::*,
|
||||
seq_file::SeqFile,
|
||||
str::CStr,
|
||||
@@ -123,6 +124,22 @@ pub trait MiscDevice: Sized {
|
||||
drop(device);
|
||||
}
|
||||
|
||||
/// Handle for mmap.
|
||||
///
|
||||
/// This function is invoked when a user space process invokes the `mmap` system call on
|
||||
/// `file`. The function is a callback that is part of the VMA initializer. The kernel will do
|
||||
/// initial setup of the VMA before calling this function. The function can then interact with
|
||||
/// the VMA initialization by calling methods of `vma`. If the function does not return an
|
||||
/// error, the kernel will complete initialization of the VMA according to the properties of
|
||||
/// `vma`.
|
||||
fn mmap(
|
||||
_device: <Self::Ptr as ForeignOwnable>::Borrowed<'_>,
|
||||
_file: &File,
|
||||
_vma: &VmaNew,
|
||||
) -> Result {
|
||||
kernel::build_error(VTABLE_DEFAULT_ERROR)
|
||||
}
|
||||
|
||||
/// Seeks this miscdevice.
|
||||
fn llseek(
|
||||
_device: <Self::Ptr as ForeignOwnable>::Borrowed<'_>,
|
||||
@@ -316,6 +333,33 @@ impl<T: MiscDevice> MiscdeviceVTable<T> {
|
||||
0
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// `file` must be a valid file that is associated with a `MiscDeviceRegistration<T>`.
|
||||
/// `vma` must be a vma that is currently being mmap'ed with this file.
|
||||
unsafe extern "C" fn mmap(
|
||||
file: *mut bindings::file,
|
||||
vma: *mut bindings::vm_area_struct,
|
||||
) -> c_int {
|
||||
// SAFETY: The mmap call of a file can access the private data.
|
||||
let private = unsafe { (*file).private_data };
|
||||
// SAFETY: This is a Rust Miscdevice, so we call `into_foreign` in `open` and
|
||||
// `from_foreign` in `release`, and `fops_mmap` is guaranteed to be called between those
|
||||
// two operations.
|
||||
let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) };
|
||||
// SAFETY: The caller provides a vma that is undergoing initial VMA setup.
|
||||
let area = unsafe { VmaNew::from_raw(vma) };
|
||||
// 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::mmap(device, file, area) {
|
||||
Ok(()) => 0,
|
||||
Err(err) => err.to_errno(),
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// `file` must be a valid file that is associated with a `MiscDeviceRegistration<T>`.
|
||||
@@ -446,6 +490,7 @@ impl<T: MiscDevice> MiscdeviceVTable<T> {
|
||||
const VTABLE: bindings::file_operations = bindings::file_operations {
|
||||
open: Some(Self::open),
|
||||
release: Some(Self::release),
|
||||
mmap: if T::HAS_MMAP { Some(Self::mmap) } else { None },
|
||||
llseek: if T::HAS_LLSEEK {
|
||||
Some(Self::llseek)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user