Skip to content

seq-file borrow #21

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

Closed
wants to merge 3 commits into from
Closed
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
14 changes: 7 additions & 7 deletions .github/workflows/busybox.config
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ CONFIG_GZIP_FAST=0
# Coreutils
#
# CONFIG_BASENAME is not set
# CONFIG_CAT is not set
CONFIG_CAT=y
# CONFIG_FEATURE_CATN is not set
# CONFIG_FEATURE_CATV is not set
# CONFIG_CHGRP is not set
Expand All @@ -209,7 +209,7 @@ CONFIG_GZIP_FAST=0
# CONFIG_CP is not set
# CONFIG_FEATURE_CP_LONG_OPTIONS is not set
# CONFIG_FEATURE_CP_REFLINK is not set
# CONFIG_CUT is not set
CONFIG_CUT=y
# CONFIG_DATE is not set
# CONFIG_FEATURE_DATE_ISOFMT is not set
# CONFIG_FEATURE_DATE_NANO is not set
Expand Down Expand Up @@ -263,9 +263,9 @@ CONFIG_GZIP_FAST=0
# CONFIG_SHA512SUM is not set
# CONFIG_SHA3SUM is not set
# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set
# CONFIG_MKDIR is not set
CONFIG_MKDIR=y
# CONFIG_MKFIFO is not set
# CONFIG_MKNOD is not set
CONFIG_MKNOD=y
# CONFIG_MKTEMP is not set
# CONFIG_MV is not set
# CONFIG_NICE is not set
Expand All @@ -280,7 +280,7 @@ CONFIG_GZIP_FAST=0
# CONFIG_READLINK is not set
# CONFIG_FEATURE_READLINK_FOLLOW is not set
# CONFIG_REALPATH is not set
# CONFIG_RM is not set
CONFIG_RM=y
# CONFIG_RMDIR is not set
# CONFIG_SEQ is not set
# CONFIG_SHRED is not set
Expand Down Expand Up @@ -449,7 +449,7 @@ CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0
# CONFIG_FEATURE_FIND_REGEX is not set
# CONFIG_FEATURE_FIND_CONTEXT is not set
# CONFIG_FEATURE_FIND_LINKS is not set
# CONFIG_GREP is not set
CONFIG_GREP=y
# CONFIG_EGREP is not set
# CONFIG_FGREP is not set
# CONFIG_FEATURE_GREP_CONTEXT is not set
Expand Down Expand Up @@ -635,7 +635,7 @@ CONFIG_DEFAULT_DEPMOD_FILE="modules.dep"
# CONFIG_MKSWAP is not set
# CONFIG_FEATURE_MKSWAP_UUID is not set
# CONFIG_MORE is not set
# CONFIG_MOUNT is not set
CONFIG_MOUNT=y
# CONFIG_FEATURE_MOUNT_FAKE is not set
# CONFIG_FEATURE_MOUNT_VERBOSE is not set
# CONFIG_FEATURE_MOUNT_HELPERS is not set
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,11 @@ jobs:
grep '] rust_semaphore_c: Rust semaphore sample (in C, for comparison) (init)$' qemu-stdout.log
grep '] rust_semaphore_c: Rust semaphore sample (in C, for comparison) (exit)$' qemu-stdout.log

- run: |
grep '] rust_seq_file: Rust seq_file sample (init)$' qemu-stdout.log
grep '] rust_seq_file: Rust seq_file sample (exit)$' qemu-stdout.log
test $(grep -c 'rust_seq_file: device opened this many times: 2' qemu-stdout.log) -eq 2

# Report
- run: |
ls -l \
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/kernel-arm-debug.config
Original file line number Diff line number Diff line change
Expand Up @@ -1780,6 +1780,7 @@ CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
CONFIG_SAMPLE_RUST_RANDOM=m
CONFIG_SAMPLE_RUST_SEQ_FILE=m
# CONFIG_STRICT_DEVMEM is not set

#
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/kernel-arm-release.config
Original file line number Diff line number Diff line change
Expand Up @@ -1704,6 +1704,7 @@ CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
CONFIG_SAMPLE_RUST_RANDOM=m
CONFIG_SAMPLE_RUST_SEQ_FILE=m
# CONFIG_STRICT_DEVMEM is not set

#
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/kernel-arm64-debug.config
Original file line number Diff line number Diff line change
Expand Up @@ -1069,7 +1069,7 @@ CONFIG_DCACHE_WORD_ACCESS=y
#
# Pseudo filesystems
#
# CONFIG_PROC_FS is not set
CONFIG_PROC_FS=y
# CONFIG_PROC_CHILDREN is not set
# CONFIG_SYSFS is not set
# CONFIG_HUGETLBFS is not set
Expand Down Expand Up @@ -1432,6 +1432,7 @@ CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
CONFIG_SAMPLE_RUST_RANDOM=m
CONFIG_SAMPLE_RUST_SEQ_FILE=m

#
# arm64 Debugging
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/kernel-arm64-release.config
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,7 @@ CONFIG_DCACHE_WORD_ACCESS=y
#
# Pseudo filesystems
#
# CONFIG_PROC_FS is not set
CONFIG_PROC_FS=y
# CONFIG_PROC_CHILDREN is not set
# CONFIG_SYSFS is not set
# CONFIG_HUGETLBFS is not set
Expand Down Expand Up @@ -1350,6 +1350,7 @@ CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
CONFIG_SAMPLE_RUST_RANDOM=m
CONFIG_SAMPLE_RUST_SEQ_FILE=m

#
# arm64 Debugging
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/kernel-ppc64le-debug.config
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,7 @@ CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
CONFIG_SAMPLE_RUST_RANDOM=m
CONFIG_SAMPLE_RUST_SEQ_FILE=m
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
# CONFIG_STRICT_DEVMEM is not set

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/kernel-ppc64le-release.config
Original file line number Diff line number Diff line change
Expand Up @@ -1454,6 +1454,7 @@ CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
CONFIG_SAMPLE_RUST_RANDOM=m
CONFIG_SAMPLE_RUST_SEQ_FILE=m
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
# CONFIG_STRICT_DEVMEM is not set

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/kernel-riscv64-debug.config
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,7 @@ CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
CONFIG_SAMPLE_RUST_RANDOM=m
CONFIG_SAMPLE_RUST_SEQ_FILE=m
# CONFIG_STRICT_DEVMEM is not set

#
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/kernel-riscv64-release.config
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,7 @@ CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
CONFIG_SAMPLE_RUST_RANDOM=m
CONFIG_SAMPLE_RUST_SEQ_FILE=m
# CONFIG_STRICT_DEVMEM is not set

#
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/kernel-x86_64-debug.config
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,7 @@ CONFIG_DCACHE_WORD_ACCESS=y
#
# Pseudo filesystems
#
# CONFIG_PROC_FS is not set
CONFIG_PROC_FS=y
# CONFIG_PROC_CHILDREN is not set
CONFIG_KERNFS=y
CONFIG_SYSFS=y
Expand Down Expand Up @@ -1444,6 +1444,7 @@ CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
CONFIG_SAMPLE_RUST_RANDOM=m
CONFIG_SAMPLE_RUST_SEQ_FILE=m
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
# CONFIG_STRICT_DEVMEM is not set

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/kernel-x86_64-release.config
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,7 @@ CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
CONFIG_SAMPLE_RUST_RANDOM=m
CONFIG_SAMPLE_RUST_SEQ_FILE=m
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
# CONFIG_STRICT_DEVMEM is not set

Expand Down
11 changes: 11 additions & 0 deletions .github/workflows/qemu-init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,15 @@ busybox insmod rust_module_parameters_loadable_custom.ko \
busybox rmmod rust_module_parameters_loadable_default.ko
busybox rmmod rust_module_parameters_loadable_custom.ko

busybox insmod rust_seq_file.ko
busybox mkdir proc
busybox mount -t proc proc /proc
export RUST_SEQ_MINOR=$(busybox cat /proc/misc | busybox grep rust_seq_file | busybox cut -d ' ' -f 1)
busybox mknod /dev/rust_seq_file0 c 10 $RUST_SEQ_MINOR
busybox cat /dev/rust_seq_file0
busybox cat /dev/rust_seq_file0
busybox cat /proc/rust_seq_file
busybox rm /dev/rust_seq_file0
busybox rmmod rust_seq_file.ko

busybox reboot -f
1 change: 1 addition & 0 deletions .github/workflows/qemu-initramfs.desc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ file /rust_miscdev.ko samples/rust/rust_miscdev.ko 0755
file /rust_stack_probing.ko samples/rust/rust_stack_probing.ko 0755 0 0
file /rust_semaphore.ko samples/rust/rust_semaphore.ko 0755 0 0
file /rust_semaphore_c.ko samples/rust/rust_semaphore_c.ko 0755 0 0
file /rust_seq_file.ko samples/rust/rust_seq_file.ko 0755 0 0

file /rust_module_parameters_loadable_default.ko samples/rust/rust_module_parameters_loadable_default.ko 0755 0 0
file /rust_module_parameters_loadable_custom.ko samples/rust/rust_module_parameters_loadable_custom.ko 0755 0 0
2 changes: 2 additions & 0 deletions rust/kernel/bindings_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include <linux/errname.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/random.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/uaccess.h>
Expand Down
7 changes: 6 additions & 1 deletion rust/kernel/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ pub mod module_param;
mod build_assert;
pub mod prelude;
pub mod print;

#[cfg(CONFIG_PROC_FS)]
pub mod proc_fs;

pub mod random;
pub mod seq_file;
mod static_assert;
pub mod sync;

Expand All @@ -80,7 +85,7 @@ pub mod user_ptr;
pub use build_error::build_error;

pub use crate::error::{Error, Result};
pub use crate::types::{Mode, ScopeGuard};
pub use crate::types::{Mode, ScopeGuard, UnsafeReference};

/// Page size defined in terms of the `PAGE_SHIFT` macro from C.
///
Expand Down
101 changes: 101 additions & 0 deletions rust/kernel/proc_fs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// SPDX-License-Identifier: GPL-2.0

//! Type for defining `proc` files.
//!
//! This module allows Rust devices to create entries in `/proc` from a
//! [`bindings::proc_ops`] vtable.
//!
//! C header: [`include/linux/proc_fs.h`](../../../include/linux/proc_fs.h)
//!
//! Reference: <https://www.kernel.org/doc/html/latest/filesystems/proc.html>

use core::{
marker::{PhantomData, Sync},
ptr,
};

use crate::{
bindings, c_types,
seq_file::{SeqFileOperationsVTable, SeqOperations},
str::CStr,
types::PointerWrapper,
Error, Result,
};

/// An entry under `/proc` containing data of type `T`.
///
/// This is the Rust equivalent to [`proc_dir_entry`] on the C side.
///
/// # Invariants
///
/// The [`ProcDirEntry::proc_dir_entry`] is a valid pointer.
/// [`ProcDirEntry::data`] points to the PDE data of
/// [`ProcDirEntry::proc_dir_entry`].
/// [`ProcDirEntry::data`] was created by a call to `T::into_pointer`.
///
/// [`proc_dir_entry`]: ../../../fs/proc/internal.h
pub struct ProcDirEntry<T: PointerWrapper> {
proc_dir_entry: *mut bindings::proc_dir_entry,
data: *const c_types::c_void,
_wrapper: PhantomData<T>,
}

// SAFETY: The `proc_dir_entry` and `data` raw pointers aren't accessible.
unsafe impl<T: PointerWrapper> Sync for ProcDirEntry<T> {}

impl<T: PointerWrapper> Drop for ProcDirEntry<T> {
fn drop(&mut self) {
// SAFETY: Calling a C function. `proc_dir_entry` is a valid pointer to
// a `bindings::proc_dir_entry` because it was created by a call to
// `proc_create_data` which only returns valid pointers.
unsafe {
bindings::proc_remove(self.proc_dir_entry);
}
// SAFETY: `self.data` was created by a call to `T::into_pointer`.
unsafe { drop(T::from_pointer(self.data)) }
}
}

impl<T: PointerWrapper> ProcDirEntry<T> {
/// Create a seq_file entry in `/proc` containing data of type `S`.
///
/// Corresponds to [`proc_create_seq_private`] on the C side.
///
/// [`proc_create_seq_private`]: ../../../fs/proc/generic.c
pub fn new_seq_private<S>(name: &CStr, data: T) -> Result<Self>
where
S: SeqOperations<DataWrapper = T>,
{
let data = data.into_pointer();
let name = name.as_char_ptr();

// SAFETY: Calling a C function. The vtable for `S` expects a
// `S::DataWrapper = T` pointer in the data field of the associated
// `proc_dir_entry`. `name` is guaranteed to be null terminated
// because it is of type `CStr`.
let proc_dir_entry = unsafe {
bindings::proc_create_seq_private(
name,
0,
ptr::null_mut(),
SeqFileOperationsVTable::<S>::build(),
0,
data as *mut c_types::c_void,
)
};
if proc_dir_entry.is_null() {
// SAFETY: `data` was created with a call to `T::into_pointer`.
drop(unsafe { T::from_pointer(data) });
Err(Error::ENOMEM)
} else {
// INVARIANT: `proc_dir_entry` is a valid pointer.
// The `data` points to the data stored in `proc_dir_entry`, and
// `data` was created by `T::into_pointer`.
Ok(ProcDirEntry {
proc_dir_entry,
data,
_wrapper: PhantomData,
})
}
}
}
Loading