samples: add first Rust examples
authorMiguel Ojeda <ojeda@kernel.org>
Sat, 3 Jul 2021 15:21:12 +0000 (17:21 +0200)
committerMiguel Ojeda <ojeda@kernel.org>
Wed, 28 Sep 2022 07:03:08 +0000 (09:03 +0200)
The beginning of a set of Rust modules that showcase how Rust
modules look like and how to use the abstracted kernel features.

It also includes an example of a Rust host program with
several modules.

These samples also double as tests in the CI.

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Finn Behrens <me@kloenk.de>
Signed-off-by: Finn Behrens <me@kloenk.de>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Milan Landaverde <milan@mdaverde.com>
Signed-off-by: Milan Landaverde <milan@mdaverde.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
samples/Kconfig
samples/Makefile
samples/rust/Kconfig [new file with mode: 0644]
samples/rust/Makefile [new file with mode: 0644]
samples/rust/hostprogs/.gitignore [new file with mode: 0644]
samples/rust/hostprogs/Makefile [new file with mode: 0644]
samples/rust/hostprogs/a.rs [new file with mode: 0644]
samples/rust/hostprogs/b.rs [new file with mode: 0644]
samples/rust/hostprogs/single.rs [new file with mode: 0644]
samples/rust/rust_minimal.rs [new file with mode: 0644]

index 470ee3b..0d81c00 100644 (file)
@@ -263,6 +263,8 @@ config SAMPLE_CORESIGHT_SYSCFG
          This demonstrates how a user may create their own CoreSight
          configurations and easily load them into the system at runtime.
 
+source "samples/rust/Kconfig"
+
 endif # SAMPLES
 
 config HAVE_SAMPLE_FTRACE_DIRECT
index 701e912..9832ef3 100644 (file)
@@ -35,3 +35,4 @@ subdir-$(CONFIG_SAMPLE_WATCH_QUEUE)   += watch_queue
 obj-$(CONFIG_DEBUG_KMEMLEAK_TEST)      += kmemleak/
 obj-$(CONFIG_SAMPLE_CORESIGHT_SYSCFG)  += coresight/
 obj-$(CONFIG_SAMPLE_FPROBE)            += fprobe/
+obj-$(CONFIG_SAMPLES_RUST)             += rust/
diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig
new file mode 100644 (file)
index 0000000..841e090
--- /dev/null
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-2.0
+
+menuconfig SAMPLES_RUST
+       bool "Rust samples"
+       depends on RUST
+       help
+         You can build sample Rust kernel code here.
+
+         If unsure, say N.
+
+if SAMPLES_RUST
+
+config SAMPLE_RUST_MINIMAL
+       tristate "Minimal"
+       help
+         This option builds the Rust minimal module sample.
+
+         To compile this as a module, choose M here:
+         the module will be called rust_minimal.
+
+         If unsure, say N.
+
+config SAMPLE_RUST_HOSTPROGS
+       bool "Host programs"
+       help
+         This option builds the Rust host program samples.
+
+         If unsure, say N.
+
+endif # SAMPLES_RUST
diff --git a/samples/rust/Makefile b/samples/rust/Makefile
new file mode 100644 (file)
index 0000000..1daba5f
--- /dev/null
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SAMPLE_RUST_MINIMAL)              += rust_minimal.o
+
+subdir-$(CONFIG_SAMPLE_RUST_HOSTPROGS)         += hostprogs
diff --git a/samples/rust/hostprogs/.gitignore b/samples/rust/hostprogs/.gitignore
new file mode 100644 (file)
index 0000000..a6c173d
--- /dev/null
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+single
diff --git a/samples/rust/hostprogs/Makefile b/samples/rust/hostprogs/Makefile
new file mode 100644 (file)
index 0000000..8ddcbd7
--- /dev/null
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+hostprogs-always-y := single
+
+single-rust := y
diff --git a/samples/rust/hostprogs/a.rs b/samples/rust/hostprogs/a.rs
new file mode 100644 (file)
index 0000000..f7a4a3d
--- /dev/null
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust single host program sample: module `a`.
+
+pub(crate) fn f(x: i32) {
+    println!("The number is {}.", x);
+}
diff --git a/samples/rust/hostprogs/b.rs b/samples/rust/hostprogs/b.rs
new file mode 100644 (file)
index 0000000..c167589
--- /dev/null
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust single host program sample: module `b`.
+
+pub(crate) const CONSTANT: i32 = 42;
diff --git a/samples/rust/hostprogs/single.rs b/samples/rust/hostprogs/single.rs
new file mode 100644 (file)
index 0000000..8c48a11
--- /dev/null
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust single host program sample.
+
+mod a;
+mod b;
+
+fn main() {
+    println!("Hello world!");
+
+    a::f(b::CONSTANT);
+}
diff --git a/samples/rust/rust_minimal.rs b/samples/rust/rust_minimal.rs
new file mode 100644 (file)
index 0000000..54ad176
--- /dev/null
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust minimal sample.
+
+use kernel::prelude::*;
+
+module! {
+    type: RustMinimal,
+    name: b"rust_minimal",
+    author: b"Rust for Linux Contributors",
+    description: b"Rust minimal sample",
+    license: b"GPL",
+}
+
+struct RustMinimal {
+    numbers: Vec<i32>,
+}
+
+impl kernel::Module for RustMinimal {
+    fn init(_module: &'static ThisModule) -> Result<Self> {
+        pr_info!("Rust minimal sample (init)\n");
+        pr_info!("Am I built-in? {}\n", !cfg!(MODULE));
+
+        let mut numbers = Vec::new();
+        numbers.try_push(72)?;
+        numbers.try_push(108)?;
+        numbers.try_push(200)?;
+
+        Ok(RustMinimal { numbers })
+    }
+}
+
+impl Drop for RustMinimal {
+    fn drop(&mut self) {
+        pr_info!("My numbers are {:?}\n", self.numbers);
+        pr_info!("Rust minimal sample (exit)\n");
+    }
+}