diff --git a/Cargo.lock b/Cargo.lock index eb5a353fb..33fb18d82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1110,6 +1110,13 @@ dependencies = [ "subtle", ] +[[package]] +name = "userdm" +version = "0.1.0" +dependencies = [ + "userlib", +] + [[package]] name = "userinit" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 76a5bdb6e..0b1d3ee6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,8 @@ members = [ "user/lib", # Init user-space module "user/init", + # device model module + "user/dm", # Release version identifier "release", ] @@ -41,6 +43,7 @@ syscall = { path = "syscall" } packit = { path = "packit" } userlib = { path = "user/lib" } userinit = { path = "user/init" } +userdm = { path = "user/dm" } release = { path = "release" } # crates.io diff --git a/configs/all-targets.json b/configs/all-targets.json index 3a4a7f820..ba0c2004a 100644 --- a/configs/all-targets.json +++ b/configs/all-targets.json @@ -53,6 +53,9 @@ "modules": { "userinit": { "path": "/init" + }, + "userdm": { + "path": "/dm" } } } diff --git a/configs/hyperv-target.json b/configs/hyperv-target.json index 4a4379cf5..57e9afc7d 100644 --- a/configs/hyperv-target.json +++ b/configs/hyperv-target.json @@ -35,6 +35,9 @@ "modules": { "userinit": { "path": "/init" + }, + "userdm": { + "path": "/dm" } } } diff --git a/configs/qemu-target.json b/configs/qemu-target.json index ceb60bd07..c292dc8a8 100644 --- a/configs/qemu-target.json +++ b/configs/qemu-target.json @@ -34,6 +34,9 @@ "modules": { "userinit": { "path": "/init" + }, + "userdm": { + "path": "/dm" } } } diff --git a/configs/vanadium-target.json b/configs/vanadium-target.json index 4a000095d..c9f6f66a3 100644 --- a/configs/vanadium-target.json +++ b/configs/vanadium-target.json @@ -35,6 +35,9 @@ "modules": { "userinit": { "path": "/init" + }, + "userdm": { + "path": "/dm" } } } diff --git a/kernel/src/svsm.rs b/kernel/src/svsm.rs index 0dccd7777..f2b5b686b 100755 --- a/kernel/src/svsm.rs +++ b/kernel/src/svsm.rs @@ -323,7 +323,7 @@ pub extern "C" fn svsm_main() { virt_log_usage(); if let Err(e) = SVSM_PLATFORM.launch_fw(&config) { - panic!("Failed to launch FW: {e:#?}"); + panic!("Failed to launch FW: {e:?}"); } start_kernel_task(request_processing_main, String::from("request-processing")) @@ -339,7 +339,7 @@ pub extern "C" fn svsm_main() { match exec_user("/init", opendir("/").expect("Failed to find FS root")) { Ok(_) => (), - Err(e) => log::info!("Failed to launch /init: {e:#?}"), + Err(e) => log::info!("Failed to launch /init: {e:?}"), } request_loop(); diff --git a/kernel/src/syscall/class0.rs b/kernel/src/syscall/class0.rs index e778df869..ce2218c2e 100644 --- a/kernel/src/syscall/class0.rs +++ b/kernel/src/syscall/class0.rs @@ -14,7 +14,10 @@ use core::ffi::c_char; use syscall::SysCallError; pub fn sys_exit(exit_code: u32) -> ! { - log::info!("Terminating current task, exit_code {exit_code}"); + log::info!( + "Terminating task {}, exit_code {exit_code}", + current_task().get_task_name() + ); unsafe { current_task_terminated(); } diff --git a/kernel/src/task/exec.rs b/kernel/src/task/exec.rs index 8b65c2389..eb8c05822 100644 --- a/kernel/src/task/exec.rs +++ b/kernel/src/task/exec.rs @@ -51,7 +51,7 @@ fn task_name(binary: &str) -> String { /// /// # Returns /// -/// `()` on success, [`SvsmError`] on failure. +/// Returns [`Ok(tid)`] on success, [`Err(SvsmError)`] on failure. pub fn exec_user(binary: &str, root: Arc) -> Result { let fh = open_read(binary)?; let file_size = fh.size(); diff --git a/user/dm/Cargo.toml b/user/dm/Cargo.toml new file mode 100644 index 000000000..6b7c35aab --- /dev/null +++ b/user/dm/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "userdm" +version = "0.1.0" +edition = "2021" + +[dependencies] +userlib.workspace = true + +[lints] +workspace = true diff --git a/user/dm/build.rs b/user/dm/build.rs new file mode 100644 index 000000000..563023a57 --- /dev/null +++ b/user/dm/build.rs @@ -0,0 +1,4 @@ +fn main() { + println!("cargo:rustc-link-arg=-Tuser/lib/module.lds"); + println!("cargo:rustc-link-arg=-no-pie"); +} diff --git a/user/dm/src/main.rs b/user/dm/src/main.rs new file mode 100644 index 000000000..192f67cfd --- /dev/null +++ b/user/dm/src/main.rs @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2024 Intel Corporation. +// +// Author: Vijay Dhanraj + +#![no_std] +#![no_main] + +use userlib::*; + +declare_main!(main); + +fn main() -> u32 { + 0 +} diff --git a/user/init/src/main.rs b/user/init/src/main.rs index 1023311b6..a73e915ef 100644 --- a/user/init/src/main.rs +++ b/user/init/src/main.rs @@ -1,41 +1,49 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2024 SUSE LLC +// +// Author: Joerg Roedel + #![no_std] #![no_main] +use core::ffi::CStr; use userlib::*; -use core::ptr::{addr_of, addr_of_mut}; - -static mut SOME_BSS_DATA: [u64; 128] = [0; 128]; -static mut SOME_DATA: [u64; 128] = [0x01; 128]; -static SOME_RO_DATA: [u64; 128] = [0xee; 128]; - -fn check(arr: &[u64; 128], val: u64) { - for v in arr.iter() { - if *v != val { - panic!("Unexpected array value"); - } - } -} - -fn write(arr: &mut [u64; 128], val: u64) { - for v in arr.iter_mut() { - *v = val; - } -} - declare_main!(main); - fn main() -> u32 { println!("COCONUT-SVSM init process starting"); - // SAFETY: Single-threaded process, so no data races. Safe to access global - // mutable data. - unsafe { - write(&mut *addr_of_mut!(SOME_DATA), 0xcc); - write(&mut *addr_of_mut!(SOME_BSS_DATA), 0xaa); - check(&*addr_of!(SOME_DATA), 0xccu64); - check(&*addr_of!(SOME_RO_DATA), 0xeeu64); - check(&*addr_of!(SOME_BSS_DATA), 0xaa); + let obj = opendir(c"/").expect("Cannot open root directory"); + + // Discover the first file under root directory, excluding `/init`. + let mut dirents: [DirEnt; 8] = Default::default(); + let binfile = loop { + let n = readdir(&obj, &mut dirents).unwrap(); + if let Some(f) = dirents + .iter() + .take(n) + .filter(|d| d.file_type == FileType::File) + .map(|d| { + CStr::from_bytes_until_nul(&d.file_name).expect("Filename is not nul-terminated!") + }) + .find(|&f| f != c"init") + { + break f; + } + if n < dirents.len() { + return 0; + } + }; + + let mut path = [b'\0'; F_NAME_SIZE + 1]; + path[0] = b'/'; + path[1..=binfile.count_bytes()].copy_from_slice(binfile.to_bytes()); + let file = CStr::from_bytes_until_nul(&path).unwrap(); + + match exec(file, c"/", 0) { + Ok(_) => 0, + Err(SysCallError::ENOTFOUND) => 1, + _ => panic!("{} launch failed", file.to_str().unwrap()), } - 0 }