diff --git a/Cargo.lock b/Cargo.lock index 5fcbc46c..4e11ee6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -446,7 +446,7 @@ dependencies = [ "axalloc", "axconfig", "axcpu", - "axplat", + "axplat 0.3.0", "axplat-aarch64-qemu-virt", "axplat-loongarch64-qemu-virt", "axplat-riscv64-qemu-virt", @@ -541,12 +541,26 @@ dependencies = [ "spin 0.10.0", ] +[[package]] +name = "axplat" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4de04c54b63bf2ca1ff202733d2516da49d7779649cdb2f9c4ecf22909e6810" +dependencies = [ + "axplat-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 2.10.0", + "const-str", + "crate_interface", + "kspin", + "memory_addr", +] + [[package]] name = "axplat" version = "0.3.0" source = "git+https://github.com/arceos-org/axplat_crates.git?tag=dev-v03#0df0713b1c20eafaeebdc6b0e194b2985e857949" dependencies = [ - "axplat-macros", + "axplat-macros 0.1.0 (git+https://github.com/arceos-org/axplat_crates.git?tag=dev-v03)", "bitflags 2.10.0", "const-str", "crate_interface", @@ -566,7 +580,7 @@ dependencies = [ "arm_pl011", "arm_pl031", "axcpu", - "axplat", + "axplat 0.3.0", "int_ratio", "kspin", "lazyinit", @@ -582,7 +596,7 @@ source = "git+https://github.com/arceos-org/axplat_crates.git?tag=dev-v03#0df071 dependencies = [ "axconfig-macros", "axcpu", - "axplat", + "axplat 0.3.0", "axplat-aarch64-peripherals", "log", "page_table_entry", @@ -595,7 +609,7 @@ source = "git+https://github.com/arceos-org/axplat_crates.git?tag=dev-v03#0df071 dependencies = [ "axconfig-macros", "axcpu", - "axplat", + "axplat 0.3.0", "chrono", "kspin", "lazyinit", @@ -608,7 +622,18 @@ dependencies = [ [[package]] name = "axplat-macros" version = "0.1.0" -source = "git+https://github.com/arceos-org/axplat_crates.git?tag=dev-v03#0df0713b1c20eafaeebdc6b0e194b2985e857949" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90dfaee06a112fe4f810c60af1a86bc080af2172185b491cacc307b84dff748" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "axplat-macros" +version = "0.1.0" +source = "git+https://github.com/arceos-org/axplat_crates.git?tag=dev-v03#72b148262f4f58a3a6c64c23d0f377e6469b662a" dependencies = [ "proc-macro2", "quote", @@ -622,7 +647,7 @@ source = "git+https://github.com/arceos-org/axplat_crates.git?tag=dev-v03#0df071 dependencies = [ "axconfig-macros", "axcpu", - "axplat", + "axplat 0.3.0", "kspin", "lazyinit", "log", @@ -640,7 +665,7 @@ source = "git+https://github.com/Starry-OS/axplat-riscv64-visionfive2.git?tag=de dependencies = [ "axconfig-macros", "axcpu", - "axplat", + "axplat 0.3.0", "kspin", "lazyinit", "log", @@ -658,7 +683,7 @@ source = "git+https://github.com/arceos-org/axplat_crates.git?tag=dev-v03#0df071 dependencies = [ "axconfig-macros", "axcpu", - "axplat", + "axplat 0.3.0", "bitflags 2.10.0", "heapless 0.9.2", "int_ratio", @@ -701,7 +726,7 @@ dependencies = [ "axlog", "axmm", "axnet", - "axplat", + "axplat 0.3.0", "axtask", "chrono", "crate_interface", @@ -1859,15 +1884,30 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_core", + "rand_core 0.9.3", ] +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + [[package]] name = "rand_core" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +[[package]] +name = "rand_pcg" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "raw-cpuid" version = "10.7.0" @@ -2149,6 +2189,7 @@ dependencies = [ "starry-core", "starry-process", "starry-signal", + "starry-vdso", ] [[package]] @@ -2199,6 +2240,7 @@ dependencies = [ "starry-core", "starry-process", "starry-signal", + "starry-vdso", "starry-vm", "syscalls", "x86", @@ -2244,6 +2286,7 @@ dependencies = [ "spin 0.10.0", "starry-process", "starry-signal", + "starry-vdso", "starry-vm", "strum", "uluru", @@ -2279,6 +2322,22 @@ dependencies = [ "strum", ] +[[package]] +name = "starry-vdso" +version = "0.1.1" +source = "git+https://github.com/Starry-OS/starry-vdso.git?rev=dab20cc#dab20ccb5d61821810ef2c8b144eccd18a950863" +dependencies = [ + "axerrno 0.2.2", + "axplat 0.2.0", + "cfg-if", + "kernel-elf-parser", + "log", + "memory_addr", + "rand_core 0.6.4", + "rand_pcg", + "xmas-elf", +] + [[package]] name = "starry-vm" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index 260506aa..f57f7894 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,6 +75,7 @@ spin = "0.10" starry-process = "0.2" starry-signal = { version = "0.2", git = "https://github.com/Starry-OS/starry-signal.git", tag = "dev-v02" } starry-vm = "0.2" +starry-vdso = { git = "https://github.com/Starry-OS/starry-vdso.git", rev = "dab20cc" } starry-core = { path = "./core" } starry-api = { path = "./api" } @@ -127,6 +128,7 @@ starry-signal.workspace = true starry-core.workspace = true starry-api.workspace = true +starry-vdso.workspace = true [dependencies.axplat-riscv64-visionfive2] version = "0.3" diff --git a/api/Cargo.toml b/api/Cargo.toml index d9d74f76..9770f568 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -60,6 +60,7 @@ spin.workspace = true starry-process.workspace = true starry-signal.workspace = true starry-vm.workspace = true +starry-vdso.workspace = true syscalls = { git = "https://github.com/Starry-OS/syscalls.git", rev = "efac241", default-features = false } zerocopy = { version = "0.8.26", features = ["derive"] } diff --git a/api/src/lib.rs b/api/src/lib.rs index e6ec362e..010f9702 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -25,9 +25,13 @@ pub fn init() { info!("Initialize VFS..."); vfs::mount_all().expect("Failed to mount vfs"); + info!("Initialize vDSO data..."); + starry_vdso::vdso::init_vdso_data(); + info!("Initialize /proc/interrupts..."); axtask::register_timer_callback(|_| { time::inc_irq_cnt(); + starry_vdso::vdso::update_vdso_data(); }); info!("Initialize alarm..."); diff --git a/api/src/syscall/task/clone.rs b/api/src/syscall/task/clone.rs index 8a567993..c7f9bc9f 100644 --- a/api/src/syscall/task/clone.rs +++ b/api/src/syscall/task/clone.rs @@ -1,3 +1,5 @@ +use core::sync::atomic::Ordering; + use alloc::sync::Arc; use axerrno::{AxError, AxResult}; @@ -180,6 +182,7 @@ pub fn sys_clone( aspace, signal_actions, exit_signal, + old_proc_data.signal.default_restorer.load(Ordering::Relaxed), ); proc_data.set_umask(old_proc_data.umask()); diff --git a/api/src/syscall/task/execve.rs b/api/src/syscall/task/execve.rs index e3da74bb..707f8af2 100644 --- a/api/src/syscall/task/execve.rs +++ b/api/src/syscall/task/execve.rs @@ -50,10 +50,14 @@ pub fn sys_execve( } let mut aspace = proc_data.aspace.lock(); - let (entry_point, user_stack_base) = + let (entry_point, user_stack_base, auxv) = load_user_app(&mut aspace, Some(path.as_str()), &args, &envs)?; drop(aspace); + let trampoline = starry_vdso::vdso::get_trampoline_addr(&auxv) + .unwrap_or(starry_core::config::SIGNAL_TRAMPOLINE); + proc_data.signal.set_default_restorer(trampoline); + let loc = FS_CONTEXT.lock().resolve(&path)?; curr.set_name(loc.name()); diff --git a/apps/vdso_test/test_getcpu.rs b/apps/vdso_test/test_getcpu.rs new file mode 100644 index 00000000..dfb515c3 --- /dev/null +++ b/apps/vdso_test/test_getcpu.rs @@ -0,0 +1,21 @@ +use std::println; + +fn main() { + println!("test_getcpu: calling init_vdso_getcpu(cpu=1, node=0)"); + + // Call the vDSO getcpu initializer from the library. + // This may require appropriate privileges on the running machine. + // If running on a non-x86_64 platform this binary will not call the + // x86_64 implementation because the crate exposes platform modules + // conditionally. + if cfg!(target_arch = "x86_64") { + // Use the crate name with hyphen turned to underscore + use starry_vdso::x86_64::getcpu::init_vdso_getcpu; + + // Example values; adjust as needed for your test environment. + init_vdso_getcpu(1u32, 0u32); + println!("init_vdso_getcpu returned (check kernel/log output for details)"); + } else { + println!("Skipping init_vdso_getcpu: not x86_64 target"); + } +} diff --git a/core/Cargo.toml b/core/Cargo.toml index 67a43e1d..4d6edb57 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -44,6 +44,7 @@ spin.workspace = true starry-process.workspace = true starry-signal.workspace = true starry-vm.workspace = true +starry-vdso.workspace = true strum = { version = "0.27.2", default-features = false, features = ["derive"] } uluru = "3.1.0" weak-map = "0.1.1" diff --git a/core/src/mm.rs b/core/src/mm.rs index e27e893e..4e98605a 100644 --- a/core/src/mm.rs +++ b/core/src/mm.rs @@ -247,10 +247,55 @@ impl ElfLoader { ldso.as_ref() .map_or_else(|| elf.entry(), |ldso| ldso.entry()), ); - let auxv = elf + let mut auxv = elf .aux_vector(PAGE_SIZE_4K, ldso.map(|elf| elf.base())) .collect::>(); + { + let uspace = core::cell::RefCell::new(&mut *uspace); + starry_vdso::vdso::load_vdso_data( + &mut auxv, + |map_user_start, vdso_paddr_page, vdso_size| { + uspace + .borrow_mut() + .map_linear( + map_user_start.into(), + vdso_paddr_page, + vdso_size, + MappingFlags::READ | MappingFlags::EXECUTE | MappingFlags::USER, + ) + .map_err(|_| AxError::InvalidExecutable) + }, + |vvar_user_addr, vvar_paddr| { + uspace + .borrow_mut() + .map_linear( + vvar_user_addr.into(), + vvar_paddr.into(), + starry_vdso::config::VVAR_PAGES * PAGE_SIZE_4K, + MappingFlags::READ | MappingFlags::USER, + ) + .map_err(|_| AxError::InvalidExecutable) + }, + |seg_user_start, seg_paddr, seg_align_size, ph| { + let mut flags = MappingFlags::USER; + if ph.flags.is_read() { + flags |= MappingFlags::READ; + } + if ph.flags.is_write() { + flags |= MappingFlags::WRITE; + } + if ph.flags.is_execute() { + flags |= MappingFlags::EXECUTE; + } + uspace + .borrow_mut() + .map_linear(seg_user_start.into(), seg_paddr, seg_align_size, flags) + .map_err(|_| AxError::InvalidExecutable) + }, + )?; + } + Ok(Ok((entry, auxv))) } } @@ -280,7 +325,7 @@ pub fn load_user_app( path: Option<&str>, args: &[String], envs: &[String], -) -> AxResult<(VirtAddr, VirtAddr)> { +) -> AxResult<(VirtAddr, VirtAddr, Vec)> { let path = path .or_else(|| args.first().map(String::as_str)) .ok_or(AxError::InvalidInput)?; @@ -347,7 +392,7 @@ pub fn load_user_app( Backend::new_alloc(heap_start, PageSize::Size4K), )?; - Ok((entry, user_sp)) + Ok((entry, user_sp, auxv)) } static ACCESSING_USER_MEM: AtomicBool = AtomicBool::new(false); diff --git a/core/src/task.rs b/core/src/task.rs index fcf77a37..c5f5b339 100644 --- a/core/src/task.rs +++ b/core/src/task.rs @@ -220,6 +220,7 @@ impl ProcessData { aspace: Arc>, signal_actions: Arc>, exit_signal: Option, + trampoline: usize, ) -> Arc { Arc::new(Self { proc, @@ -238,7 +239,7 @@ impl ProcessData { signal: Arc::new(ProcessSignalManager::new( signal_actions, - crate::config::SIGNAL_TRAMPOLINE, + trampoline, )), futex_table: Arc::new(FutexTable::new()), diff --git a/src/entry.rs b/src/entry.rs index 65a23d52..12002952 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -31,7 +31,7 @@ pub fn run_initproc(args: &[String], envs: &[String]) -> i32 { .expect("Failed to get executable absolute path"); let name = loc.name(); - let (entry_vaddr, ustack_top) = load_user_app(&mut uspace, None, args, envs) + let (entry_vaddr, ustack_top, auxv) = load_user_app(&mut uspace, None, args, envs) .unwrap_or_else(|e| panic!("Failed to load user app: {}", e)); let uctx = UserContext::new(entry_vaddr.into(), ustack_top, 0); @@ -52,6 +52,8 @@ pub fn run_initproc(args: &[String], envs: &[String]) -> i32 { Arc::new(Mutex::new(uspace)), Arc::default(), None, + starry_vdso::vdso::get_trampoline_addr(&auxv) + .unwrap_or(starry_core::config::SIGNAL_TRAMPOLINE), ); { let mut scope = proc_data.scope.write();