Skip to content

Add charp and some primitive param types #82

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -153,18 +153,23 @@ jobs:
# Run
- run: ${{ env.BUILD_DIR }}usr/gen_init_cpio .github/workflows/qemu-initramfs.desc > qemu-initramfs.img

- run: qemu-system-${{ env.QEMU_ARCH }} -kernel ${{ env.BUILD_DIR }}${{ env.IMAGE_PATH }} -initrd qemu-initramfs.img -M ${{ env.QEMU_MACHINE }} -cpu ${{ env.QEMU_CPU }} -smp 2 -nographic -no-reboot -append '${{ env.QEMU_APPEND }} rust_example.my_i32=123321 rust_example_2.my_i32=234432' | tee qemu-stdout.log
- run: qemu-system-${{ env.QEMU_ARCH }} -kernel ${{ env.BUILD_DIR }}${{ env.IMAGE_PATH }} -initrd qemu-initramfs.img -M ${{ env.QEMU_MACHINE }} -cpu ${{ env.QEMU_CPU }} -smp 2 -nographic -no-reboot -append '${{ env.QEMU_APPEND }} rust_example.my_i32=123321 rust_example.my_str=🦀mod rust_example.my_invbool=y rust_example_2.my_i32=234432' | tee qemu-stdout.log

# Check
- run: grep -F '] Rust Example (init)' qemu-stdout.log
- run: grep -F '] [2] Rust Example (init)' qemu-stdout.log
- run: grep -F '] [3] Rust Example (init)' qemu-stdout.log
- run: grep -F '] [4] Rust Example (init)' qemu-stdout.log

- run: "grep -F '] my_i32: 123321' qemu-stdout.log"
- run: "grep -F '] [2] my_i32: 234432' qemu-stdout.log"
- run: "grep -F '] [3] my_i32: 345543' qemu-stdout.log"
- run: "grep -F '] [4] my_i32: 456654' qemu-stdout.log"
- run: "grep -F '] my_i32: 123321' qemu-stdout.log"
- run: "grep -F '] [2] my_i32: 234432' qemu-stdout.log"
- run: "grep -F '] [3] my_i32: 345543' qemu-stdout.log"
- run: "grep -F '] [4] my_i32: 456654' qemu-stdout.log"

- run: "grep '\\] my_str: 🦀mod\\s*$' qemu-stdout.log"
- run: "grep '\\] \\[2\\] my_str: default str val\\s*$' qemu-stdout.log"
- run: "grep '\\] \\[3\\] my_str: 🦀mod\\s*$' qemu-stdout.log"
- run: "grep '\\] \\[4\\] my_str: default str val\\s*$' qemu-stdout.log"

- run: grep -F '] [3] Rust Example (exit)' qemu-stdout.log
- run: grep -F '] [4] Rust Example (exit)' qemu-stdout.log
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/qemu-init.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh

busybox insmod rust_example_3.ko my_i32=345543
busybox insmod rust_example_3.ko my_i32=345543 my_str=🦀mod
busybox insmod rust_example_4.ko my_i32=456654
busybox rmmod rust_example_3.ko
busybox rmmod rust_example_4.ko
Expand Down
18 changes: 15 additions & 3 deletions drivers/char/rust_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ module! {
permissions: 0o644,
description: b"Example of i32",
},
my_str: str {
default: b"default str val",
permissions: 0o644,
description: b"Example of a string param",
},
},
}

Expand All @@ -49,9 +54,16 @@ impl KernelModule for RustExample {
fn init() -> KernelResult<Self> {
println!("Rust Example (init)");
println!("Am I built-in? {}", !cfg!(MODULE));
println!("Parameters:");
println!(" my_bool: {}", my_bool.read());
println!(" my_i32: {}", my_i32.read());
{
let lock = THIS_MODULE.kernel_param_lock();
println!("Parameters:");
println!(" my_bool: {}", my_bool.read());
println!(" my_i32: {}", my_i32.read(&lock));
println!(
" my_str: {}",
core::str::from_utf8(my_str.read(&lock))?
);
}

// Including this large variable on the stack will trigger
// stack probing on the supported archs.
Expand Down
18 changes: 15 additions & 3 deletions drivers/char/rust_example_2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ module! {
permissions: 0o644,
description: b"Example of i32",
},
my_str: str {
default: b"default str val",
permissions: 0o644,
description: b"Example of a string param",
},
},
}

Expand All @@ -34,9 +39,16 @@ impl KernelModule for RustExample2 {
fn init() -> KernelResult<Self> {
println!("[2] Rust Example (init)");
println!("[2] Am I built-in? {}", !cfg!(MODULE));
println!("[2] Parameters:");
println!("[2] my_bool: {}", my_bool.read());
println!("[2] my_i32: {}", my_i32.read());
{
let lock = THIS_MODULE.kernel_param_lock();
println!("[2] Parameters:");
println!("[2] my_bool: {}", my_bool.read());
println!("[2] my_i32: {}", my_i32.read(&lock));
println!(
"[2] my_str: {}",
core::str::from_utf8(my_str.read(&lock))?
);
}

// Including this large variable on the stack will trigger
// stack probing on the supported archs.
Expand Down
18 changes: 15 additions & 3 deletions drivers/char/rust_example_3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ module! {
permissions: 0o644,
description: b"Example of i32",
},
my_str: str {
default: b"default str val",
permissions: 0o644,
description: b"Example of a string param",
},
},
}

Expand All @@ -34,9 +39,16 @@ impl KernelModule for RustExample3 {
fn init() -> KernelResult<Self> {
println!("[3] Rust Example (init)");
println!("[3] Am I built-in? {}", !cfg!(MODULE));
println!("[3] Parameters:");
println!("[3] my_bool: {}", my_bool.read());
println!("[3] my_i32: {}", my_i32.read());
{
let lock = THIS_MODULE.kernel_param_lock();
println!("[3] Parameters:");
println!("[3] my_bool: {}", my_bool.read());
println!("[3] my_i32: {}", my_i32.read(&lock));
println!(
"[3] my_str: {}",
core::str::from_utf8(my_str.read(&lock))?
);
}

// Including this large variable on the stack will trigger
// stack probing on the supported archs.
Expand Down
18 changes: 15 additions & 3 deletions drivers/char/rust_example_4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ module! {
permissions: 0o644,
description: b"Example of i32",
},
my_str: str {
default: b"default str val",
permissions: 0o644,
description: b"Example of a string param",
},
},
}

Expand All @@ -34,9 +39,16 @@ impl KernelModule for RustExample4 {
fn init() -> KernelResult<Self> {
println!("[4] Rust Example (init)");
println!("[4] Am I built-in? {}", !cfg!(MODULE));
println!("[4] Parameters:");
println!("[4] my_bool: {}", my_bool.read());
println!("[4] my_i32: {}", my_i32.read());
{
let lock = THIS_MODULE.kernel_param_lock();
println!("[4] Parameters:");
println!("[4] my_bool: {}", my_bool.read());
println!("[4] my_i32: {}", my_i32.read(&lock));
println!(
"[4] my_str: {}",
core::str::from_utf8(my_str.read(&lock))?
);
}

// Including this large variable on the stack will trigger
// stack probing on the supported archs.
Expand Down
15 changes: 15 additions & 0 deletions rust/kernel/c_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,18 @@ mod c {
}

pub use c::*;

/// Reads string until null byte is reached and returns slice excluding the terminating null.
///
/// # Safety
///
/// The data from the pointer until the null terminator must be valid for reads
/// and not mutated for all of `'a`. The length of the string must also be less
/// than `isize::MAX`. See the documentation on [`from_raw_parts`] for further
/// details on safety of converting a pointer to a slice.
///
/// [`from_raw_parts`]: https://doc.rust-lang.org/core/slice/fn.from_raw_parts.html
pub unsafe fn c_string_bytes<'a>(ptr: *const crate::c_types::c_char) -> &'a [u8] {
let length = crate::bindings::strlen(ptr) as usize;
&core::slice::from_raw_parts(ptr as *const u8, length)
}
7 changes: 7 additions & 0 deletions rust/kernel/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0

use core::num::TryFromIntError;
use core::str::Utf8Error;

use alloc::alloc::AllocError;

Expand Down Expand Up @@ -31,6 +32,12 @@ impl From<TryFromIntError> for Error {
}
}

impl From<Utf8Error> for Error {
fn from(_: Utf8Error) -> Error {
Error::EINVAL
}
}

pub type KernelResult<T> = Result<T, Error>;

impl From<AllocError> for Error {
Expand Down
24 changes: 24 additions & 0 deletions rust/kernel/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,30 @@ impl ThisModule {
pub const unsafe fn from_ptr(ptr: *mut bindings::module) -> ThisModule {
ThisModule(ptr)
}

pub fn kernel_param_lock(&self) -> KParamGuard<'_> {
// SAFETY: `kernel_param_lock` will check if the pointer is null and use the built-in mutex
// in that case.
#[cfg(CONFIG_SYSFS)]
unsafe { bindings::kernel_param_lock(self.0) }

KParamGuard { this_module: self }
}
}

/// Scoped lock on the kernel parameters of `ThisModule`. Lock will be released
/// when this struct is dropped.
pub struct KParamGuard<'a> {
this_module: &'a ThisModule
}

#[cfg(CONFIG_SYSFS)]
impl<'a> Drop for KParamGuard<'a> {
fn drop(&mut self) {
// SAFETY: `kernel_param_lock` will check if the pointer is null and use the built-in mutex
// in that case. The existance of `self` guarantees that the lock is held.
unsafe { bindings::kernel_param_unlock(self.this_module.0) }
}
}

extern "C" {
Expand Down
Loading