mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	When building the kernel on Arch Linux using on x86_64 with tools: $ rustc --version rustc 1.84.0 (9fc6b4312 2025-01-07) $ clang --version clang version 19.1.7 Target: x86_64-pc-linux-gnu The following symbols are generated: $ nm vmlinux | rg ' _R' | rustfilt | rg faux ffffffff81959ae0 T <kernel::faux::Registration>::new ffffffff81959b40 T <kernel::faux::Registration as core::ops::drop::Drop>::drop However, these Rust symbols are wrappers around bindings in the C faux code. Inlining these functions removes the middle-man wrapper function After applying this patch, the above function signatures disappear. Link: https://github.com/Rust-for-Linux/linux/issues/1145 Signed-off-by: Ethan Carter Edwards <ethan@ethancedwards.com> Acked-by: Danilo Krummrich <dakr@kernel.org> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/jesg4yu7m6fvzmgg5tlsktrrjm36l4qsranto5mdmnucx4pvf3@nhvt4juw5es3 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
		
			
				
	
	
		
			77 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
// SPDX-License-Identifier: GPL-2.0-only
 | 
						|
 | 
						|
//! Abstractions for the faux bus.
 | 
						|
//!
 | 
						|
//! This module provides bindings for working with faux devices in kernel modules.
 | 
						|
//!
 | 
						|
//! C header: [`include/linux/device/faux.h`]
 | 
						|
 | 
						|
use crate::{bindings, device, error::code::*, prelude::*};
 | 
						|
use core::ptr::{addr_of_mut, null, null_mut, NonNull};
 | 
						|
 | 
						|
/// The registration of a faux device.
 | 
						|
///
 | 
						|
/// This type represents the registration of a [`struct faux_device`]. When an instance of this type
 | 
						|
/// is dropped, its respective faux device will be unregistered from the system.
 | 
						|
///
 | 
						|
/// # Invariants
 | 
						|
///
 | 
						|
/// `self.0` always holds a valid pointer to an initialized and registered [`struct faux_device`].
 | 
						|
///
 | 
						|
/// [`struct faux_device`]: srctree/include/linux/device/faux.h
 | 
						|
pub struct Registration(NonNull<bindings::faux_device>);
 | 
						|
 | 
						|
impl Registration {
 | 
						|
    /// Create and register a new faux device with the given name.
 | 
						|
    #[inline]
 | 
						|
    pub fn new(name: &CStr, parent: Option<&device::Device>) -> Result<Self> {
 | 
						|
        // SAFETY:
 | 
						|
        // - `name` is copied by this function into its own storage
 | 
						|
        // - `faux_ops` is safe to leave NULL according to the C API
 | 
						|
        // - `parent` can be either NULL or a pointer to a `struct device`, and `faux_device_create`
 | 
						|
        //   will take a reference to `parent` using `device_add` - ensuring that it remains valid
 | 
						|
        //   for the lifetime of the faux device.
 | 
						|
        let dev = unsafe {
 | 
						|
            bindings::faux_device_create(
 | 
						|
                name.as_char_ptr(),
 | 
						|
                parent.map_or(null_mut(), |p| p.as_raw()),
 | 
						|
                null(),
 | 
						|
            )
 | 
						|
        };
 | 
						|
 | 
						|
        // The above function will return either a valid device, or NULL on failure
 | 
						|
        // INVARIANT: The device will remain registered until faux_device_destroy() is called, which
 | 
						|
        // happens in our Drop implementation.
 | 
						|
        Ok(Self(NonNull::new(dev).ok_or(ENODEV)?))
 | 
						|
    }
 | 
						|
 | 
						|
    fn as_raw(&self) -> *mut bindings::faux_device {
 | 
						|
        self.0.as_ptr()
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
impl AsRef<device::Device> for Registration {
 | 
						|
    fn as_ref(&self) -> &device::Device {
 | 
						|
        // SAFETY: The underlying `device` in `faux_device` is guaranteed by the C API to be
 | 
						|
        // a valid initialized `device`.
 | 
						|
        unsafe { device::Device::as_ref(addr_of_mut!((*self.as_raw()).dev)) }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
impl Drop for Registration {
 | 
						|
    #[inline]
 | 
						|
    fn drop(&mut self) {
 | 
						|
        // SAFETY: `self.0` is a valid registered faux_device via our type invariants.
 | 
						|
        unsafe { bindings::faux_device_destroy(self.as_raw()) }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
// SAFETY: The faux device API is thread-safe as guaranteed by the device core, as long as
 | 
						|
// faux_device_destroy() is guaranteed to only be called once - which is guaranteed by our type not
 | 
						|
// having Copy/Clone.
 | 
						|
unsafe impl Send for Registration {}
 | 
						|
 | 
						|
// SAFETY: The faux device API is thread-safe as guaranteed by the device core, as long as
 | 
						|
// faux_device_destroy() is guaranteed to only be called once - which is guaranteed by our type not
 | 
						|
// having Copy/Clone.
 | 
						|
unsafe impl Sync for Registration {}
 |