1 // SPDX-License-Identifier: GPL-2.0
3 //! Crate for all kernel procedural macros.
14 use proc_macro::TokenStream;
16 /// Declares a kernel module.
18 /// The `type` argument should be a type which implements the [`Module`]
19 /// trait. Also accepts various forms of kernel metadata.
21 /// C header: [`include/linux/moduleparam.h`](../../../include/linux/moduleparam.h)
23 /// [`Module`]: ../kernel/trait.Module.html
28 /// use kernel::prelude::*;
32 /// name: "my_kernel_module",
33 /// author: "Rust for Linux Contributors",
34 /// description: "My very own kernel module!",
39 /// permissions: 0o000,
40 /// description: "Example of i32",
42 /// writeable_i32: i32 {
44 /// permissions: 0o644,
45 /// description: "Example of i32",
52 /// impl kernel::Module for MyModule {
53 /// fn init() -> Result<Self> {
54 /// // If the parameter is writeable, then the kparam lock must be
55 /// // taken to read the parameter:
57 /// let lock = THIS_MODULE.kernel_param_lock();
58 /// pr_info!("i32 param is: {}\n", writeable_i32.read(&lock));
60 /// // If the parameter is read only, it can be read without locking
61 /// // the kernel parameters:
62 /// pr_info!("i32 param is: {}\n", my_i32.read());
68 /// # Supported argument types
69 /// - `type`: type which implements the [`Module`] trait (required).
70 /// - `name`: byte array of the name of the kernel module (required).
71 /// - `author`: byte array of the author of the kernel module.
72 /// - `description`: byte array of the description of the kernel module.
73 /// - `license`: byte array of the license of the kernel module (required).
74 /// - `alias`: byte array of alias name of the kernel module.
76 pub fn module(ts: TokenStream) -> TokenStream {
80 /// Declares or implements a vtable trait.
82 /// Linux's use of pure vtables is very close to Rust traits, but they differ
83 /// in how unimplemented functions are represented. In Rust, traits can provide
84 /// default implementation for all non-required methods (and the default
85 /// implementation could just return `Error::EINVAL`); Linux typically use C
86 /// `NULL` pointers to represent these functions.
88 /// This attribute is intended to close the gap. Traits can be declared and
89 /// implemented with the `#[vtable]` attribute, and a `HAS_*` associated constant
90 /// will be generated for each method in the trait, indicating if the implementor
91 /// has overridden a method.
93 /// This attribute is not needed if all methods are required.
98 /// use kernel::prelude::*;
100 /// // Declares a `#[vtable]` trait
102 /// pub trait Operations: Send + Sync + Sized {
103 /// fn foo(&self) -> Result<()> {
107 /// fn bar(&self) -> Result<()> {
114 /// // Implements the `#[vtable]` trait
116 /// impl Operations for Foo {
117 /// fn foo(&self) -> Result<()> {
123 /// assert_eq!(<Foo as Operations>::HAS_FOO, true);
124 /// assert_eq!(<Foo as Operations>::HAS_BAR, false);
126 #[proc_macro_attribute]
127 pub fn vtable(attr: TokenStream, ts: TokenStream) -> TokenStream {
128 vtable::vtable(attr, ts)
131 /// Concatenate two identifiers.
133 /// This is useful in macros that need to declare or reference items with names
134 /// starting with a fixed prefix and ending in a user specified name. The resulting
135 /// identifier has the span of the second argument.
140 /// use kernel::macro::concat_idents;
142 /// macro_rules! pub_no_prefix {
143 /// ($prefix:ident, $($newname:ident),+) => {
144 /// $(pub(crate) const $newname: u32 = kernel::macros::concat_idents!($prefix, $newname);)+
149 /// binder_driver_return_protocol_,
155 /// BR_TRANSACTION_COMPLETE,
163 /// BR_CLEAR_DEATH_NOTIFICATION_DONE,
167 /// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK);
170 pub fn concat_idents(ts: TokenStream) -> TokenStream {
171 concat_idents::concat_idents(ts)
174 /// Used to specify the pinning information of the fields of a struct.
176 /// This is somewhat similar in purpose as
177 /// [pin-project-lite](https://crates.io/crates/pin-project-lite).
178 /// Place this macro on a struct definition and then `#[pin]` in front of the attributes of each
179 /// field you want to structurally pin.
181 /// This macro enables the use of the [`pin_init!`] macro. When pin-initializing a `struct`,
182 /// then `#[pin]` directs the type of initializer that is required.
184 /// If your `struct` implements `Drop`, then you need to add `PinnedDrop` as arguments to this
185 /// macro, and change your `Drop` implementation to `PinnedDrop` annotated with
186 /// `#[`[`macro@pinned_drop`]`]`, since dropping pinned values requires extra care.
192 /// struct DriverData {
194 /// queue: Mutex<Vec<Command>>,
195 /// buf: Box<[u8; 1024 * 1024]>,
200 /// #[pin_data(PinnedDrop)]
201 /// struct DriverData {
203 /// queue: Mutex<Vec<Command>>,
204 /// buf: Box<[u8; 1024 * 1024]>,
205 /// raw_info: *mut Info,
209 /// impl PinnedDrop for DriverData {
210 /// fn drop(self: Pin<&mut Self>) {
211 /// unsafe { bindings::destroy_info(self.raw_info) };
216 /// [`pin_init!`]: ../kernel/macro.pin_init.html
217 // ^ cannot use direct link, since `kernel` is not a dependency of `macros`.
218 #[proc_macro_attribute]
219 pub fn pin_data(inner: TokenStream, item: TokenStream) -> TokenStream {
220 pin_data::pin_data(inner, item)
223 /// Used to implement `PinnedDrop` safely.
225 /// Only works on structs that are annotated via `#[`[`macro@pin_data`]`]`.
230 /// #[pin_data(PinnedDrop)]
231 /// struct DriverData {
233 /// queue: Mutex<Vec<Command>>,
234 /// buf: Box<[u8; 1024 * 1024]>,
235 /// raw_info: *mut Info,
239 /// impl PinnedDrop for DriverData {
240 /// fn drop(self: Pin<&mut Self>) {
241 /// unsafe { bindings::destroy_info(self.raw_info) };
245 #[proc_macro_attribute]
246 pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {
247 pinned_drop::pinned_drop(args, input)