Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ea20127
add draft to support WebAssembly within the kernel
stlankes Jun 21, 2024
0b38f7e
switch to wasmtime 22.0
stlankes Jun 21, 2024
a474a8b
add license text to the derived implementation of setjmp/longjmp
stlankes Jun 22, 2024
8becfea
update wasm example
stlankes Jun 22, 2024
d358204
remove compiler warnings
stlankes Jun 22, 2024
a0e4e5f
prepare wasm support for aarch64 and riscv64
stlankes Jun 22, 2024
801e760
extend demo with a small benchmark
stlankes Jun 23, 2024
4089cd8
remove some compiler warnings
stlankes Jun 23, 2024
2231f2d
switch to wasmtime 24.0 and enable RISCV support
stlankes Aug 25, 2024
8048f02
add draft of wasm support within the kernel
stlankes Jul 22, 2025
8328585
fix(fd_write): break on incomplete write
mkroening Jul 22, 2025
87c04a7
fix(fd_write): don't use system call
mkroening Jul 22, 2025
9725151
handle wasm io to a asynchronous task
stlankes Jul 24, 2025
f3a39af
using IO interface instead calling the console
stlankes Jul 24, 2025
5bfb7c1
revise interface to allocate physical / virtual memory regions
stlankes Jul 24, 2025
d288c3d
extend linker to run C programs in kernel space
stlankes Jul 26, 2025
6e2a3fb
allow WASM to write data in a file
stlankes Jul 28, 2025
3c6a0e6
remove blocking locks in async tasks
stlankes Jul 28, 2025
d3a598d
avoid the usage of blocking spinlock by polling the wasm interface
stlankes Aug 31, 2025
15de924
using try_lock instead of lock
stlankes Sep 1, 2025
fb6213c
call wasm function to trace the network traffic
stlankes Sep 1, 2025
d9aa35e
remove clippy warnings and some typos
stlankes Sep 1, 2025
3738fc8
disable code, which is only necessary to measure the performance of wasm
stlankes Sep 2, 2025
0f26efd
define wasi as optional
stlankes Sep 2, 2025
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
691 changes: 537 additions & 154 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ vga = []
virtio = ["dep:virtio"]
virtio-net = ["virtio"]
vsock = ["virtio", "pci"]
wasm = ["wasmtime", "wasi", "mmap"]

[lints.rust]
rust_2018_idioms = "warn"
Expand Down Expand Up @@ -144,6 +145,8 @@ time = { version = "0.3", default-features = false }
volatile = "0.6"
zerocopy = { version = "0.8", default-features = false }
uhyve-interface = "0.1.3"
wasmtime = { version = "34.0.2", default-features = false, features = ["runtime", "custom-virtual-memory"], optional = true }
wasi = { version = "0.11", default-features = false, optional = true }

[dependencies.smoltcp]
version = "0.12"
Expand Down
18 changes: 18 additions & 0 deletions src/arch/aarch64/kernel/longjmp.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# The code is derived from the musl implementation
# of longjmp.
.section .text
.global longjmp
longjmp:
# IHI0055B_aapcs64.pdf 5.1.1, 5.1.2 callee saved registers
ldp x19, x20, [x0,#0]
ldp x21, x22, [x0,#16]
ldp x23, x24, [x0,#32]
ldp x25, x26, [x0,#48]
ldp x27, x28, [x0,#64]
ldp x29, x30, [x0,#80]
ldr x2, [x0,#104]
mov sp, x2

cmp w1, 0
csinc w0, w1, wzr, ne
br x30
3 changes: 3 additions & 0 deletions src/arch/aarch64/kernel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ use crate::arch::aarch64::mm::paging::{BasePageSize, PageSize};
use crate::config::*;
use crate::env;

global_asm!(include_str!("setjmp.s"));
global_asm!(include_str!("longjmp.s"));

#[repr(align(8))]
pub(crate) struct AlignedAtomicU32(AtomicU32);

Expand Down
16 changes: 16 additions & 0 deletions src/arch/aarch64/kernel/setjmp.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# The code is derived from the musl implementation
# of setjmp.
.section .text
.global setjmp
setjmp:
# IHI0055B_aapcs64.pdf 5.1.1, 5.1.2 callee saved registers
stp x19, x20, [x0,#0]
stp x21, x22, [x0,#16]
stp x23, x24, [x0,#32]
stp x25, x26, [x0,#48]
stp x27, x28, [x0,#64]
stp x29, x30, [x0,#80]
mov x2, sp
str x2, [x0,#104]
mov x0, #0
ret
23 changes: 23 additions & 0 deletions src/arch/riscv64/kernel/longjmp.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# The code is derived from the musl implementation
# of longjmp.
.section .text
.global longjmp
longjmp:
ld s0, 0(a0)
ld s1, 8(a0)
ld s2, 16(a0)
ld s3, 24(a0)
ld s4, 32(a0)
ld s5, 40(a0)
ld s6, 48(a0)
ld s7, 56(a0)
ld s8, 64(a0)
ld s9, 72(a0)
ld s10, 80(a0)
ld s11, 88(a0)
ld sp, 96(a0)
ld ra, 104(a0)

seqz a0, a1
add a0, a0, a1
ret
4 changes: 4 additions & 0 deletions src/arch/riscv64/kernel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod start;
pub mod switch;
pub mod systemtime;
use alloc::vec::Vec;
use core::arch::global_asm;
use core::ptr;
use core::sync::atomic::{AtomicPtr, AtomicU32, AtomicU64, Ordering};

Expand All @@ -35,6 +36,9 @@ use crate::env;
use crate::init_cell::InitCell;
use crate::mm::physicalmem::PHYSICAL_FREE_LIST;

global_asm!(include_str!("setjmp.s"));
global_asm!(include_str!("longjmp.s"));

// Used to store information about available harts. The index of the hart in the vector
// represents its CpuId and does not need to match its hart_id
pub(crate) static HARTS_AVAILABLE: InitCell<Vec<usize>> = InitCell::new(Vec::new());
Expand Down
22 changes: 22 additions & 0 deletions src/arch/riscv64/kernel/setjmp.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# The code is derived from the musl implementation
# of setjmp.
.section .text
.global setjmp
setjmp:
sd s0, 0(a0)
sd s1, 8(a0)
sd s2, 16(a0)
sd s3, 24(a0)
sd s4, 32(a0)
sd s5, 40(a0)
sd s6, 48(a0)
sd s7, 56(a0)
sd s8, 64(a0)
sd s9, 72(a0)
sd s10, 80(a0)
sd s11, 88(a0)
sd sp, 96(a0)
sd ra, 104(a0)

li a0, 0
ret
19 changes: 19 additions & 0 deletions src/arch/x86_64/kernel/longjmp.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# The code is derived from the musl implementation
# of longjmp.
#
# Copyright 2011-2012 Nicholas J. Kain,
# licensed under standard MIT license
.section .text
.global longjmp
longjmp:
xor eax,eax
cmp esi, 1 /* CF = val ? 0 : 1 */
adc eax, esi /* eax = val + !val */
mov rbx, [rdi]
mov rbp, [rdi+8]
mov r12, [rdi+16]
mov r13, [rdi+24]
mov r14, [rdi+32]
mov r15, [rdi+40]
mov rsp, [rdi+48]
jmp [rdi+56]
4 changes: 4 additions & 0 deletions src/arch/x86_64/kernel/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[cfg(feature = "common-os")]
use core::arch::asm;
use core::arch::global_asm;
use core::ptr;
use core::sync::atomic::{AtomicPtr, AtomicU32, Ordering};

Expand Down Expand Up @@ -42,6 +43,9 @@ pub(crate) mod systemtime;
#[cfg(feature = "vga")]
pub mod vga;

global_asm!(include_str!("setjmp.s"));
global_asm!(include_str!("longjmp.s"));

pub fn get_ram_address() -> PhysAddr {
PhysAddr::new(env::boot_info().hardware_info.phys_addr_range.start)
}
Expand Down
20 changes: 20 additions & 0 deletions src/arch/x86_64/kernel/setjmp.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# The code is derived from the musl implementation
# of setjmp.
#
# Copyright 2011-2012 Nicholas J. Kain,
# licensed under standard MIT license
.section .text
.global setjmp
setjmp:
mov [rdi], rbx
mov [rdi+8], rbp
mov [rdi+16], r12
mov [rdi+24], r13
mov [rdi+32], r14
mov [rdi+40], r15
lea rdx, [rsp+8] # rsp without current ret addr
mov [rdi+48], rdx
mov rdi, rsp # save return addr ptr for new rip
mov [rdi+56], rdx
xor rax, rax
ret
4 changes: 2 additions & 2 deletions src/arch/x86_64/mm/paging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ pub fn map<S>(
if let Ok((_frame, flush)) = unmap {
unmapped = true;
flush.flush();
debug!("Had to unmap page {page:?} before mapping.");
trace!("Had to unmap page {page:?} before mapping.");
}
let map = unsafe { mapper.map_to(page, frame, flags, &mut *frame_allocator) };
match map {
Expand Down Expand Up @@ -267,7 +267,7 @@ where
// FIXME: Some sentinel pages around stacks are supposed to be unmapped.
// We should handle this case there instead of here.
Err(UnmapError::PageNotMapped) => {
debug!("Tried to unmap {page:?}, which was not mapped.");
trace!("Tried to unmap {page:?}, which was not mapped.");
}
Err(err) => panic!("{err:?}"),
}
Expand Down
14 changes: 14 additions & 0 deletions src/drivers/net/virtio/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,12 @@ impl smoltcp::phy::TxToken for TxToken<'_> {
result
};

#[cfg(feature = "wasm")]
if let Some(ref mut wasm_manager) = crate::wasm::WASM_MANAGER.lock().as_mut() {
crate::wasm::INPUT.lock().push_back(packet.to_vec());
let _ = wasm_manager.call_func::<(), ()>("pcap_writer", ());
}

let mut header = Box::new_in(<Hdr as Default>::default(), DeviceAlloc);

// If a checksum calculation by the host is necessary, we have to inform the host within the header
Expand Down Expand Up @@ -361,6 +367,14 @@ impl smoltcp::phy::RxToken for RxToken<'_> {
.unwrap();
}

#[cfg(feature = "wasm")]
if let Some(ref mut wasm_manager) = crate::wasm::WASM_MANAGER.lock().as_mut() {
crate::wasm::INPUT
.lock()
.push_back(combined_packets.to_vec());
let _ = wasm_manager.call_func::<(), ()>("pcap_writer", ());
}

f(&combined_packets)
}
}
Expand Down
17 changes: 11 additions & 6 deletions src/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,18 @@ pub(crate) fn run() {

/// Spawns a future on the executor.
#[cfg_attr(
not(any(feature = "shell", feature = "tcp", feature = "udp", feature = "vsock")),
not(any(
feature = "shell",
feature = "tcp",
feature = "udp",
feature = "vsock",
feature = "wasm"
)),
expect(dead_code)
)]
pub(crate) fn spawn<F>(future: F)
where
F: Future<Output = ()> + Send + 'static,
F: Future<Output = ()> + 'static + core::marker::Send,
{
core_local::ex().spawn(AsyncTask::new(future)).detach();
}
Expand Down Expand Up @@ -169,19 +175,18 @@ where
{
if let Some(mut guard) = crate::executor::network::NIC.try_lock() {
let delay = if let Ok(nic) = guard.as_nic_mut() {
nic.set_polling_mode(false);

nic.poll_delay(Instant::from_micros_const(now.try_into().unwrap()))
.map(|d| d.total_micros())
} else {
None
};

core_local::core_scheduler().add_network_timer(
delay.map(|d| crate::arch::processor::get_timer_ticks() + d),
);
}

if let Ok(device) = crate::executor::network::NIC.lock().as_nic_mut() {
device.set_polling_mode(false);
}
}

return t;
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ mod shell;
mod synch;
pub mod syscalls;
pub mod time;
#[cfg(feature = "wasm")]
pub mod wasm;

mod built_info {
include!(concat!(env!("OUT_DIR"), "/built.rs"));
Expand Down
Loading
Loading