Skip to content

Seq file proc redo #19

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 4 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 @@ -324,6 +324,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 @@ -1665,6 +1665,7 @@ CONFIG_SAMPLE_RUST_MISCDEV=m
CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=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 @@ -1589,6 +1589,7 @@ CONFIG_SAMPLE_RUST_MISCDEV=m
CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=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 @@ -1431,6 +1431,7 @@ CONFIG_SAMPLE_RUST_MISCDEV=m
CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=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 @@ -1349,6 +1349,7 @@ CONFIG_SAMPLE_RUST_MISCDEV=m
CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=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 @@ -1491,6 +1491,7 @@ CONFIG_SAMPLE_RUST_MISCDEV=m
CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=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 @@ -1453,6 +1453,7 @@ CONFIG_SAMPLE_RUST_MISCDEV=m
CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=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 @@ -1353,6 +1353,7 @@ CONFIG_SAMPLE_RUST_MISCDEV=m
CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
CONFIG_SAMPLE_RUST_SEQ_FILE=m
# CONFIG_SAMPLE_RUST_RANDOM is not set
# 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 @@ -1318,6 +1318,7 @@ CONFIG_SAMPLE_RUST_MISCDEV=m
CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
CONFIG_SAMPLE_RUST_SEQ_FILE=m
# CONFIG_SAMPLE_RUST_RANDOM is not set
# 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 @@ -1443,6 +1443,7 @@ CONFIG_SAMPLE_RUST_MISCDEV=m
CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=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 @@ -1391,6 +1391,7 @@ CONFIG_SAMPLE_RUST_MISCDEV=m
CONFIG_SAMPLE_RUST_STACK_PROBING=m
CONFIG_SAMPLE_RUST_SEMAPHORE=m
CONFIG_SAMPLE_RUST_SEMAPHORE_C=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
6 changes: 6 additions & 0 deletions rust/kernel/bindings_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
#include <linux/cdev.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 All @@ -13,6 +15,10 @@
#include <linux/mm.h>
#include <uapi/linux/android/binder.h>

#ifdef CONFIG_PROC_FS
#include "../../fs/proc/internal.h"
#endif

// `bindgen` gets confused at certain things
const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL;
const gfp_t BINDINGS___GFP_ZERO = __GFP_ZERO;
5 changes: 5 additions & 0 deletions rust/kernel/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ pub mod module_param;

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 Down
82 changes: 82 additions & 0 deletions rust/kernel/proc_fs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// 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 alloc::boxed::Box;
use core::{
marker::{PhantomData, Sync},
ops::Deref,
ptr,
};

use crate::{bindings, c_types, CStr, Error, KernelResult};

/// An entry under `/proc` containing data of type `T`.
///
/// This is the Rust equivalent to [`proc_dir_entry`] on the C side.
///
/// # Invariants
///
/// The pointer [`ProcDirEntry::proc_dir_entry`] is a valid pointer and
/// it's field [`bindings::proc_dir_entry::data`] is a valid pointer to
/// `T`.
///
/// [`proc_dir_entry`]: ../../../fs/proc/internal.h
pub struct ProcDirEntry<T> {
proc_dir_entry: *mut bindings::proc_dir_entry,
data: PhantomData<T>,
}

// SAFETY: The `proc_dir_entry` raw pointer isn't accessible.
unsafe impl<T> Sync for ProcDirEntry<T> {}

impl<T> Drop for ProcDirEntry<T> {
fn drop(&mut self) {
// SAFETY: `ProcDirEntry` is guaranteed to have a valid pointer to `T`
// in the `data` field of `proc_dir_entry`.
let data = unsafe { Box::from_raw((*self.proc_dir_entry).data as *mut T) };
// 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);
}
drop(data);
}
}

/// Create an entry in `/proc` containing data of type `T`.
///
/// Corresponds to [`proc_create_data`] on the C side.
///
/// [`proc_create_data]: ../../../fs/proc/generic.c
pub(crate) fn proc_create_data<T>(
name: CStr<'static>,
proc_ops: &'static bindings::proc_ops,
data: T,
) -> KernelResult<ProcDirEntry<T>> {
let data_ptr = Box::into_raw(Box::try_new(data)?) as *mut c_types::c_void;
let name = name.deref().as_ptr() as *const u8 as *const c_types::c_char;

// SAFETY: Calling a C function. `name` is guaranteed to be null terminated
// because it is of type `CStr`.
let proc_dir_entry =
unsafe { bindings::proc_create_data(name, 0, ptr::null_mut(), proc_ops, data_ptr) };
if proc_dir_entry.is_null() {
Err(Error::ENOMEM)
} else {
// INVARIANT: `proc_dir_entry` is a valid pointer and it's data field
// is a valid pointer to `T`.
Ok(ProcDirEntry {
proc_dir_entry,
data: PhantomData,
})
}
}
Loading