Skip to content

Commit

Permalink
rust: add static_key_false
Browse files Browse the repository at this point in the history
This method is deprecated in C, but we are still adding it here because
we are mirroring how C implements tracepoints, and tracepoints use
static_key_false.

Signed-off-by: Alice Ryhl <[email protected]>
  • Loading branch information
Darksonn committed Jun 3, 2024
1 parent 6accae1 commit c3ded95
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 1 deletion.
3 changes: 3 additions & 0 deletions rust/kernel/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#![feature(new_uninit)]
#![feature(receiver_trait)]
#![feature(unsize)]
#![feature(asm_const)]
#![feature(asm_goto)]

// Ensure conditional compilation based on the kernel configuration works;
// otherwise we may silently break things like initcall handling.
Expand All @@ -39,6 +41,7 @@ pub mod prelude;
pub mod print;
mod static_assert;
pub mod static_call;
pub mod static_key;
#[doc(hidden)]
pub mod std_vendor;
pub mod str;
Expand Down
150 changes: 150 additions & 0 deletions rust/kernel/static_key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// SPDX-License-Identifier: GPL-2.0

// Copyright (C) 2024 Google LLC.

//! Logic for static keys.
use crate::bindings::*;

#[doc(hidden)]
#[macro_export]
#[cfg(target_arch = "x86_64")]
#[cfg(not(CONFIG_HAVE_RUST_ASM_GOTO))]
macro_rules! _static_key_false {
($key:path, $keytyp:ty, $field:ident) => {{
let mut output = 1u32;

core::arch::asm!(
r#"
1: .byte 0x0f,0x1f,0x44,0x00,0x00
.pushsection __jump_table, "aw"
.balign 8
.long 1b - .
.long 3f - .
.quad {0} + {1} - .
.popsection
2: mov {2:e}, 0
3:
"#,
sym $key,
const ::core::mem::offset_of!($keytyp, $field),
inout(reg) output,
);

output != 0
}};
}

#[doc(hidden)]
#[macro_export]
#[cfg(target_arch = "x86_64")]
#[cfg(CONFIG_HAVE_RUST_ASM_GOTO)]
macro_rules! _static_key_false {
($key:path, $keytyp:ty, $field:ident) => {'my_label: {
core::arch::asm!(
r#"
1: .byte 0x0f,0x1f,0x44,0x00,0x00
.pushsection __jump_table, "aw"
.balign 8
.long 1b - .
.long {0} - .
.quad {1} + {2} - .
.popsection
"#,
label {
break 'my_label true;
},
sym $key,
const ::core::mem::offset_of!($keytyp, $field),
);

break 'my_label false;
}};
}

#[doc(hidden)]
#[macro_export]
#[cfg(target_arch = "aarch64")]
#[cfg(not(CONFIG_HAVE_RUST_ASM_GOTO))]
macro_rules! _static_key_false {
($key:path, $keytyp:ty, $field:ident) => {{
let mut output = 1u32;

core::arch::asm!(
r#"
1: nop
.pushsection __jump_table, "aw"
.align 3
.long 1b - ., 3f - .
.quad {0} + {1} - .
.popsection
2: mov {2:w}, 0
3:
"#,
sym $key,
const ::core::mem::offset_of!($keytyp, $field),
inout(reg) output
);

output != 0
}};
}

#[doc(hidden)]
#[macro_export]
#[cfg(target_arch = "aarch64")]
#[cfg(CONFIG_HAVE_RUST_ASM_GOTO)]
macro_rules! _static_key_false {
($key:path, $keytyp:ty, $field:ident) => {'my_label: {
core::arch::asm!(
r#"
1: nop
.pushsection __jump_table, "aw"
.align 3
.long 1b - ., {0} - .
.quad {1} + {2} - .
.popsection
"#,
label {
break 'my_label true;
},
sym $key,
const ::core::mem::offset_of!($keytyp, $field),
);

break 'my_label false;
}};
}

/// Branch based on a static key.
///
/// Takes three arguments:
///
/// * `key` - the path to the static variable containing the `static_key`.
/// * `keytyp` - the type of `key`.
/// * `field` - the name of the field of `key` that contains the `static_key`.
#[macro_export]
macro_rules! static_key_false {
// Forward to the real implementation. Separated like this so that we don't have to duplicate
// the documentation.
($key:path, $keytyp:ty, $field:ident) => {{
// Assert that `$key` has type `$keytyp` and that `$key.$field` has type `static_key`.
//
// SAFETY: We know that `$key` is a static because otherwise the inline assembly will not
// compile. The raw pointers created in this block are in-bounds of `$key`.
const _: () = unsafe {
let key: *const $keytyp = ::core::mem::addr_of!($key);
let _: *const $crate::bindings::static_key = ::core::mem::addr_of!((*key).$field);
};

$crate::static_key::_static_key_false! { $($args)* }
}};
}

pub use {_static_key_false, static_key_false};
2 changes: 1 addition & 1 deletion scripts/Makefile.build
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ $(obj)/%.lst: $(obj)/%.c FORCE
# Compile Rust sources (.rs)
# ---------------------------------------------------------------------------

rust_allowed_features := new_uninit
rust_allowed_features := asm_const,asm_goto,new_uninit

# `--out-dir` is required to avoid temporaries being created by `rustc` in the
# current working directory, which may be not accessible in the out-of-tree
Expand Down

0 comments on commit c3ded95

Please sign in to comment.