From bbd28a65dcbebe69e1dee497b6df7db1a2c49d46 Mon Sep 17 00:00:00 2001 From: muou000 Date: Mon, 1 Dec 2025 21:09:14 +0800 Subject: [PATCH 01/10] feat(vdso): add vDSO support --- Cargo.lock | 85 ++++++++++++++++++++++++---- Cargo.toml | 1 + api/Cargo.toml | 1 + api/src/lib.rs | 8 +++ core/Cargo.toml | 1 + core/src/lib.rs | 1 + core/src/mm.rs | 4 +- core/src/vdso.rs | 142 +++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 231 insertions(+), 12 deletions(-) create mode 100644 core/src/vdso.rs diff --git a/Cargo.lock b/Cargo.lock index 5fcbc46c..28380f15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -358,6 +358,14 @@ dependencies = [ "log", ] +[[package]] +name = "axerrno" +version = "0.1.0" +source = "git+https://github.com/Starry-OS/axerrno.git?rev=f1e2bca#f1e2bcac2c016fefb568c8af62b8c893aab9fba5" +dependencies = [ + "log", +] + [[package]] name = "axerrno" version = "0.1.2" @@ -446,7 +454,7 @@ dependencies = [ "axalloc", "axconfig", "axcpu", - "axplat", + "axplat 0.3.0", "axplat-aarch64-qemu-virt", "axplat-loongarch64-qemu-virt", "axplat-riscv64-qemu-virt", @@ -541,12 +549,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 +588,7 @@ dependencies = [ "arm_pl011", "arm_pl031", "axcpu", - "axplat", + "axplat 0.3.0", "int_ratio", "kspin", "lazyinit", @@ -582,7 +604,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 +617,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 +630,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 +655,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 +673,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 +691,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 +734,7 @@ dependencies = [ "axlog", "axmm", "axnet", - "axplat", + "axplat 0.3.0", "axtask", "chrono", "crate_interface", @@ -1859,15 +1892,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" @@ -2199,6 +2247,7 @@ dependencies = [ "starry-core", "starry-process", "starry-signal", + "starry-vdso", "starry-vm", "syscalls", "x86", @@ -2244,6 +2293,7 @@ dependencies = [ "spin 0.10.0", "starry-process", "starry-signal", + "starry-vdso", "starry-vm", "strum", "uluru", @@ -2279,6 +2329,19 @@ dependencies = [ "strum", ] +[[package]] +name = "starry-vdso" +version = "0.1.1" +source = "git+https://github.com/muou000/starry-vdso.git?rev=710ccb5#710ccb59f68a50ebcdb536df4eb0169ba8c8c3bf" +dependencies = [ + "axerrno 0.1.0", + "axplat 0.2.0", + "log", + "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..d6484bba 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/muou000/starry-vdso.git", rev = "710ccb5" } starry-core = { path = "./core" } starry-api = { path = "./api" } 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..0e436051 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -25,9 +25,17 @@ pub fn init() { info!("Initialize VFS..."); vfs::mount_all().expect("Failed to mount vfs"); + // Enable user-space access to timer counter registers on aarch64 + #[cfg(target_arch = "aarch64")] + starry_vdso::vdso::enable_cntvct_access(); + + 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/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/lib.rs b/core/src/lib.rs index c4e8e09c..7518e47a 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -17,4 +17,5 @@ pub mod resources; pub mod shm; pub mod task; pub mod time; +pub mod vdso; pub mod vfs; diff --git a/core/src/mm.rs b/core/src/mm.rs index e27e893e..091ce38a 100644 --- a/core/src/mm.rs +++ b/core/src/mm.rs @@ -247,10 +247,12 @@ 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::>(); + crate::vdso::load_vdso_data(&mut auxv, uspace)?; + Ok(Ok((entry, auxv))) } } diff --git a/core/src/vdso.rs b/core/src/vdso.rs new file mode 100644 index 00000000..d78d6770 --- /dev/null +++ b/core/src/vdso.rs @@ -0,0 +1,142 @@ +//! vDSO data management. + +extern crate alloc; +extern crate axlog; +use alloc::vec::Vec; + +use axerrno::{AxError, AxResult}; +use axhal::paging::MappingFlags; +use axmm::AddrSpace; +use kernel_elf_parser::{AuxEntry, AuxType}; +use memory_addr::{MemoryAddr, PAGE_SIZE_4K}; +use starry_vdso::vdso::{VdsoAllocGuard, prepare_vdso_pages, vdso_data_paddr}; + +/// Load vDSO into the given user address space and update auxv accordingly. +pub fn load_vdso_data(auxv: &mut Vec, uspace: &mut AddrSpace) -> AxResult<()> { + let (vdso_kstart, vdso_kend) = unsafe { starry_vdso::embed::init_vdso_symbols() }; + info!("vdso_kstart: {vdso_kstart:#x}, vdso_kend: {vdso_kend:#x}",); + + if vdso_kend <= vdso_kstart { + warn!( + "vDSO binary is missing or invalid: vdso_kstart={vdso_kstart:#x}, \ + vdso_kend={vdso_kend:#x}. vDSO will not be loaded and AT_SYSINFO_EHDR will not be \ + set." + ); + return Err(AxError::InvalidExecutable); + } + + let (vdso_paddr_page, vdso_bytes, vdso_size, vdso_page_offset, alloc_info) = + prepare_vdso_pages(vdso_kstart, vdso_kend).map_err(|_| AxError::InvalidExecutable)?; + + let mut alloc_guard = VdsoAllocGuard::new(alloc_info); + + let (_base_addr, vdso_user_addr) = + starry_vdso::vdso::calculate_vdso_aslr_addr(vdso_kstart, vdso_kend, vdso_page_offset); + + match kernel_elf_parser::ELFHeadersBuilder::new(vdso_bytes).and_then(|b| { + let range = b.ph_range(); + b.build(&vdso_bytes[range.start as usize..range.end as usize]) + }) { + Ok(headers) => { + map_vdso_segments( + headers, + vdso_user_addr, + vdso_paddr_page, + vdso_page_offset, + uspace, + )?; + alloc_guard.disarm(); + } + Err(_) => { + info!("vDSO ELF parsing failed, using fallback mapping"); + let map_user_start = if vdso_page_offset == 0 { + vdso_user_addr + } else { + vdso_user_addr - vdso_page_offset + }; + uspace + .map_linear( + map_user_start.into(), + vdso_paddr_page, + vdso_size, + MappingFlags::READ | MappingFlags::EXECUTE | MappingFlags::USER, + ) + .map_err(|_| AxError::InvalidExecutable)?; + alloc_guard.disarm(); + } + } + + map_vvar_and_push_aux(auxv, vdso_user_addr, uspace)?; + + Ok(()) +} + +fn map_vvar_and_push_aux( + auxv: &mut Vec, + vdso_user_addr: usize, + uspace: &mut AddrSpace, +) -> AxResult<()> { + use starry_vdso::config::VVAR_PAGES; + let vvar_user_addr = vdso_user_addr - VVAR_PAGES * PAGE_SIZE_4K; + let vvar_paddr = vdso_data_paddr(); + + uspace + .map_linear( + vvar_user_addr.into(), + vvar_paddr.into(), + 2 * PAGE_SIZE_4K, + MappingFlags::READ | MappingFlags::USER, + ) + .map_err(|_| AxError::InvalidExecutable)?; + + info!( + "Mapped vvar pages at user {:#x}..{:#x} -> paddr {:#x}", + vvar_user_addr, + vvar_user_addr + VVAR_PAGES * PAGE_SIZE_4K, + vvar_paddr, + ); + + let aux_entry = AuxEntry::new(AuxType::SYSINFO_EHDR, vdso_user_addr); + auxv.push(aux_entry); + + Ok(()) +} + +fn map_vdso_segments( + headers: kernel_elf_parser::ELFHeaders, + vdso_user_addr: usize, + vdso_paddr_page: axhal::mem::PhysAddr, + vdso_page_offset: usize, + uspace: &mut AddrSpace, +) -> AxResult<()> { + info!("vDSO ELF parsed successfully, mapping segments"); + for ph in headers + .ph + .iter() + .filter(|ph| ph.get_type() == Ok(xmas_elf::program::Type::Load)) + { + let vaddr = ph.virtual_addr as usize; + let seg_pad = vaddr.align_offset_4k() + vdso_page_offset; + let seg_align_size = + (ph.mem_size as usize + seg_pad + PAGE_SIZE_4K - 1) & !(PAGE_SIZE_4K - 1); + + let map_base_user = vdso_user_addr & !(PAGE_SIZE_4K - 1); + let seg_user_start = map_base_user + vaddr.align_down_4k(); + let seg_paddr = vdso_paddr_page + vaddr.align_down_4k(); + + 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 + .map_linear(seg_user_start.into(), seg_paddr, seg_align_size, flags) + .map_err(|_| AxError::InvalidExecutable)?; + } + Ok(()) +} From ba446b4f374b4775051b7fb531ea243ce8a09975 Mon Sep 17 00:00:00 2001 From: muou Date: Mon, 1 Dec 2025 21:25:52 +0800 Subject: [PATCH 02/10] Update core/src/vdso.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- core/src/vdso.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/vdso.rs b/core/src/vdso.rs index d78d6770..ee5dcf06 100644 --- a/core/src/vdso.rs +++ b/core/src/vdso.rs @@ -14,7 +14,7 @@ use starry_vdso::vdso::{VdsoAllocGuard, prepare_vdso_pages, vdso_data_paddr}; /// Load vDSO into the given user address space and update auxv accordingly. pub fn load_vdso_data(auxv: &mut Vec, uspace: &mut AddrSpace) -> AxResult<()> { let (vdso_kstart, vdso_kend) = unsafe { starry_vdso::embed::init_vdso_symbols() }; - info!("vdso_kstart: {vdso_kstart:#x}, vdso_kend: {vdso_kend:#x}",); + info!("vdso_kstart: {vdso_kstart:#x}, vdso_kend: {vdso_kend:#x}"); if vdso_kend <= vdso_kstart { warn!( From cac75496b23e47f66925e67e9424fd0f5f647df1 Mon Sep 17 00:00:00 2001 From: muou000 Date: Tue, 2 Dec 2025 08:37:57 +0800 Subject: [PATCH 03/10] chore: update starry-vdso dependency source --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 28380f15..665c87d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2332,7 +2332,7 @@ dependencies = [ [[package]] name = "starry-vdso" version = "0.1.1" -source = "git+https://github.com/muou000/starry-vdso.git?rev=710ccb5#710ccb59f68a50ebcdb536df4eb0169ba8c8c3bf" +source = "git+https://github.com/Starry-OS/starry-vdso.git?rev=a19a3da#a19a3da9d84a13f318b8dea1f9fc4e3fe50b90d0" dependencies = [ "axerrno 0.1.0", "axplat 0.2.0", diff --git a/Cargo.toml b/Cargo.toml index d6484bba..7e6e875f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +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/muou000/starry-vdso.git", rev = "710ccb5" } +starry-vdso = { git = "https://github.com/Starry-OS/starry-vdso.git", rev = "a19a3da" } starry-core = { path = "./core" } starry-api = { path = "./api" } From 25a111126f08442d38ad9cbe4512b77bc15ecc59 Mon Sep 17 00:00:00 2001 From: muou Date: Tue, 2 Dec 2025 11:23:57 +0800 Subject: [PATCH 04/10] Update core/src/vdso.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- core/src/vdso.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/vdso.rs b/core/src/vdso.rs index ee5dcf06..bb68023b 100644 --- a/core/src/vdso.rs +++ b/core/src/vdso.rs @@ -84,7 +84,7 @@ fn map_vvar_and_push_aux( .map_linear( vvar_user_addr.into(), vvar_paddr.into(), - 2 * PAGE_SIZE_4K, + VVAR_PAGES * PAGE_SIZE_4K, MappingFlags::READ | MappingFlags::USER, ) .map_err(|_| AxError::InvalidExecutable)?; From 4e06bf84fde85b980b5c7fa0bd2ec335ac8ed0a7 Mon Sep 17 00:00:00 2001 From: muou000 Date: Thu, 4 Dec 2025 14:54:01 +0800 Subject: [PATCH 05/10] chore: update starry-vdso --- Cargo.lock | 3 ++- Cargo.toml | 2 +- core/src/vdso.rs | 16 ++++++++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 665c87d2..2447676a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2332,10 +2332,11 @@ dependencies = [ [[package]] name = "starry-vdso" version = "0.1.1" -source = "git+https://github.com/Starry-OS/starry-vdso.git?rev=a19a3da#a19a3da9d84a13f318b8dea1f9fc4e3fe50b90d0" +source = "git+https://github.com/Starry-OS/starry-vdso.git?rev=06fa83e#06fa83e2a07a87f6db905d2ad9d92a9b642d1404" dependencies = [ "axerrno 0.1.0", "axplat 0.2.0", + "cfg-if", "log", "rand_core 0.6.4", "rand_pcg", diff --git a/Cargo.toml b/Cargo.toml index 7e6e875f..427c9d35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +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 = "a19a3da" } +starry-vdso = { git = "https://github.com/Starry-OS/starry-vdso.git", rev = "06fa83e" } starry-core = { path = "./core" } starry-api = { path = "./api" } diff --git a/core/src/vdso.rs b/core/src/vdso.rs index bb68023b..791785b2 100644 --- a/core/src/vdso.rs +++ b/core/src/vdso.rs @@ -9,11 +9,23 @@ use axhal::paging::MappingFlags; use axmm::AddrSpace; use kernel_elf_parser::{AuxEntry, AuxType}; use memory_addr::{MemoryAddr, PAGE_SIZE_4K}; -use starry_vdso::vdso::{VdsoAllocGuard, prepare_vdso_pages, vdso_data_paddr}; +use starry_vdso::{ + guard::VdsoAllocGuard, + vdso::{prepare_vdso_pages, vdso_data_paddr}, +}; /// Load vDSO into the given user address space and update auxv accordingly. pub fn load_vdso_data(auxv: &mut Vec, uspace: &mut AddrSpace) -> AxResult<()> { - let (vdso_kstart, vdso_kend) = unsafe { starry_vdso::embed::init_vdso_symbols() }; + unsafe extern "C" { + static vdso_start: u8; + static vdso_end: u8; + } + let (vdso_kstart, vdso_kend) = unsafe { + ( + &vdso_start as *const u8 as usize, + &vdso_end as *const u8 as usize, + ) + }; info!("vdso_kstart: {vdso_kstart:#x}, vdso_kend: {vdso_kend:#x}"); if vdso_kend <= vdso_kstart { From 42e6388225b3443e2abcd6fd10c45525e7bf8f75 Mon Sep 17 00:00:00 2001 From: muou000 Date: Thu, 4 Dec 2025 15:38:35 +0800 Subject: [PATCH 06/10] chore: update starry-vdso --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2447676a..24f3941d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2332,7 +2332,7 @@ dependencies = [ [[package]] name = "starry-vdso" version = "0.1.1" -source = "git+https://github.com/Starry-OS/starry-vdso.git?rev=06fa83e#06fa83e2a07a87f6db905d2ad9d92a9b642d1404" +source = "git+https://github.com/Starry-OS/starry-vdso.git?rev=699c0e0#699c0e09bfb40703fd285159da4bf0bf7f27c701" dependencies = [ "axerrno 0.1.0", "axplat 0.2.0", diff --git a/Cargo.toml b/Cargo.toml index 427c9d35..d69305e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +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 = "06fa83e" } +starry-vdso = { git = "https://github.com/Starry-OS/starry-vdso.git", rev = "699c0e0" } starry-core = { path = "./core" } starry-api = { path = "./api" } From 3f3a1c0b5d0db67af24d88025e3d004afded72c0 Mon Sep 17 00:00:00 2001 From: muou000 Date: Fri, 12 Dec 2025 16:22:13 +0800 Subject: [PATCH 07/10] chore: update starry-vdso dependency --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24f3941d..77a86484 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2332,7 +2332,7 @@ dependencies = [ [[package]] name = "starry-vdso" version = "0.1.1" -source = "git+https://github.com/Starry-OS/starry-vdso.git?rev=699c0e0#699c0e09bfb40703fd285159da4bf0bf7f27c701" +source = "git+https://github.com/Starry-OS/starry-vdso.git?rev=8f1ab42#8f1ab423f9f6d7f612aae3f6fd85e164ccb0c5a6" dependencies = [ "axerrno 0.1.0", "axplat 0.2.0", diff --git a/Cargo.toml b/Cargo.toml index d69305e0..94eca33a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +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 = "699c0e0" } +starry-vdso = { git = "https://github.com/Starry-OS/starry-vdso.git", rev = "8f1ab42" } starry-core = { path = "./core" } starry-api = { path = "./api" } From 5f636ea37efb705b2c9a61d300f3c445d271fa4d Mon Sep 17 00:00:00 2001 From: muou000 Date: Fri, 12 Dec 2025 16:25:39 +0800 Subject: [PATCH 08/10] fix: delete enable CNTVCT function --- api/src/lib.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/api/src/lib.rs b/api/src/lib.rs index 0e436051..010f9702 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -25,10 +25,6 @@ pub fn init() { info!("Initialize VFS..."); vfs::mount_all().expect("Failed to mount vfs"); - // Enable user-space access to timer counter registers on aarch64 - #[cfg(target_arch = "aarch64")] - starry_vdso::vdso::enable_cntvct_access(); - info!("Initialize vDSO data..."); starry_vdso::vdso::init_vdso_data(); From b4de37b44aa29033504d14335df452805dbf9436 Mon Sep 17 00:00:00 2001 From: muou000 Date: Tue, 16 Dec 2025 10:07:45 +0800 Subject: [PATCH 09/10] refactor: update starry-vdso dependency and remove vDSO module --- Cargo.lock | 14 ++--- Cargo.toml | 2 +- core/src/lib.rs | 1 - core/src/mm.rs | 45 +++++++++++++- core/src/vdso.rs | 154 ----------------------------------------------- 5 files changed, 49 insertions(+), 167 deletions(-) delete mode 100644 core/src/vdso.rs diff --git a/Cargo.lock b/Cargo.lock index 77a86484..55951aec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -358,14 +358,6 @@ dependencies = [ "log", ] -[[package]] -name = "axerrno" -version = "0.1.0" -source = "git+https://github.com/Starry-OS/axerrno.git?rev=f1e2bca#f1e2bcac2c016fefb568c8af62b8c893aab9fba5" -dependencies = [ - "log", -] - [[package]] name = "axerrno" version = "0.1.2" @@ -2332,12 +2324,14 @@ dependencies = [ [[package]] name = "starry-vdso" version = "0.1.1" -source = "git+https://github.com/Starry-OS/starry-vdso.git?rev=8f1ab42#8f1ab423f9f6d7f612aae3f6fd85e164ccb0c5a6" +source = "git+https://github.com/Starry-OS/starry-vdso.git?rev=cf2d4a6#cf2d4a6a2245b0aa8caa15d5faa8cce305f4e9d8" dependencies = [ - "axerrno 0.1.0", + "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", diff --git a/Cargo.toml b/Cargo.toml index 94eca33a..fe036a04 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +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 = "8f1ab42" } +starry-vdso = { git = "https://github.com/Starry-OS/starry-vdso.git", rev = "cf2d4a6" } starry-core = { path = "./core" } starry-api = { path = "./api" } diff --git a/core/src/lib.rs b/core/src/lib.rs index 7518e47a..c4e8e09c 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -17,5 +17,4 @@ pub mod resources; pub mod shm; pub mod task; pub mod time; -pub mod vdso; pub mod vfs; diff --git a/core/src/mm.rs b/core/src/mm.rs index 091ce38a..b615c90c 100644 --- a/core/src/mm.rs +++ b/core/src/mm.rs @@ -251,7 +251,50 @@ impl ElfLoader { .aux_vector(PAGE_SIZE_4K, ldso.map(|elf| elf.base())) .collect::>(); - crate::vdso::load_vdso_data(&mut auxv, uspace)?; + { + 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))) } diff --git a/core/src/vdso.rs b/core/src/vdso.rs deleted file mode 100644 index 791785b2..00000000 --- a/core/src/vdso.rs +++ /dev/null @@ -1,154 +0,0 @@ -//! vDSO data management. - -extern crate alloc; -extern crate axlog; -use alloc::vec::Vec; - -use axerrno::{AxError, AxResult}; -use axhal::paging::MappingFlags; -use axmm::AddrSpace; -use kernel_elf_parser::{AuxEntry, AuxType}; -use memory_addr::{MemoryAddr, PAGE_SIZE_4K}; -use starry_vdso::{ - guard::VdsoAllocGuard, - vdso::{prepare_vdso_pages, vdso_data_paddr}, -}; - -/// Load vDSO into the given user address space and update auxv accordingly. -pub fn load_vdso_data(auxv: &mut Vec, uspace: &mut AddrSpace) -> AxResult<()> { - unsafe extern "C" { - static vdso_start: u8; - static vdso_end: u8; - } - let (vdso_kstart, vdso_kend) = unsafe { - ( - &vdso_start as *const u8 as usize, - &vdso_end as *const u8 as usize, - ) - }; - info!("vdso_kstart: {vdso_kstart:#x}, vdso_kend: {vdso_kend:#x}"); - - if vdso_kend <= vdso_kstart { - warn!( - "vDSO binary is missing or invalid: vdso_kstart={vdso_kstart:#x}, \ - vdso_kend={vdso_kend:#x}. vDSO will not be loaded and AT_SYSINFO_EHDR will not be \ - set." - ); - return Err(AxError::InvalidExecutable); - } - - let (vdso_paddr_page, vdso_bytes, vdso_size, vdso_page_offset, alloc_info) = - prepare_vdso_pages(vdso_kstart, vdso_kend).map_err(|_| AxError::InvalidExecutable)?; - - let mut alloc_guard = VdsoAllocGuard::new(alloc_info); - - let (_base_addr, vdso_user_addr) = - starry_vdso::vdso::calculate_vdso_aslr_addr(vdso_kstart, vdso_kend, vdso_page_offset); - - match kernel_elf_parser::ELFHeadersBuilder::new(vdso_bytes).and_then(|b| { - let range = b.ph_range(); - b.build(&vdso_bytes[range.start as usize..range.end as usize]) - }) { - Ok(headers) => { - map_vdso_segments( - headers, - vdso_user_addr, - vdso_paddr_page, - vdso_page_offset, - uspace, - )?; - alloc_guard.disarm(); - } - Err(_) => { - info!("vDSO ELF parsing failed, using fallback mapping"); - let map_user_start = if vdso_page_offset == 0 { - vdso_user_addr - } else { - vdso_user_addr - vdso_page_offset - }; - uspace - .map_linear( - map_user_start.into(), - vdso_paddr_page, - vdso_size, - MappingFlags::READ | MappingFlags::EXECUTE | MappingFlags::USER, - ) - .map_err(|_| AxError::InvalidExecutable)?; - alloc_guard.disarm(); - } - } - - map_vvar_and_push_aux(auxv, vdso_user_addr, uspace)?; - - Ok(()) -} - -fn map_vvar_and_push_aux( - auxv: &mut Vec, - vdso_user_addr: usize, - uspace: &mut AddrSpace, -) -> AxResult<()> { - use starry_vdso::config::VVAR_PAGES; - let vvar_user_addr = vdso_user_addr - VVAR_PAGES * PAGE_SIZE_4K; - let vvar_paddr = vdso_data_paddr(); - - uspace - .map_linear( - vvar_user_addr.into(), - vvar_paddr.into(), - VVAR_PAGES * PAGE_SIZE_4K, - MappingFlags::READ | MappingFlags::USER, - ) - .map_err(|_| AxError::InvalidExecutable)?; - - info!( - "Mapped vvar pages at user {:#x}..{:#x} -> paddr {:#x}", - vvar_user_addr, - vvar_user_addr + VVAR_PAGES * PAGE_SIZE_4K, - vvar_paddr, - ); - - let aux_entry = AuxEntry::new(AuxType::SYSINFO_EHDR, vdso_user_addr); - auxv.push(aux_entry); - - Ok(()) -} - -fn map_vdso_segments( - headers: kernel_elf_parser::ELFHeaders, - vdso_user_addr: usize, - vdso_paddr_page: axhal::mem::PhysAddr, - vdso_page_offset: usize, - uspace: &mut AddrSpace, -) -> AxResult<()> { - info!("vDSO ELF parsed successfully, mapping segments"); - for ph in headers - .ph - .iter() - .filter(|ph| ph.get_type() == Ok(xmas_elf::program::Type::Load)) - { - let vaddr = ph.virtual_addr as usize; - let seg_pad = vaddr.align_offset_4k() + vdso_page_offset; - let seg_align_size = - (ph.mem_size as usize + seg_pad + PAGE_SIZE_4K - 1) & !(PAGE_SIZE_4K - 1); - - let map_base_user = vdso_user_addr & !(PAGE_SIZE_4K - 1); - let seg_user_start = map_base_user + vaddr.align_down_4k(); - let seg_paddr = vdso_paddr_page + vaddr.align_down_4k(); - - 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 - .map_linear(seg_user_start.into(), seg_paddr, seg_align_size, flags) - .map_err(|_| AxError::InvalidExecutable)?; - } - Ok(()) -} From 8f313e626420eb6c7d916a30d7b8dc536165c588 Mon Sep 17 00:00:00 2001 From: muou000 Date: Mon, 22 Dec 2025 09:22:28 +0800 Subject: [PATCH 10/10] feat: use vdso for sigreturn trampoline --- Cargo.lock | 3 ++- Cargo.toml | 3 ++- api/src/syscall/task/clone.rs | 3 +++ api/src/syscall/task/execve.rs | 6 +++++- apps/vdso_test/test_getcpu.rs | 21 +++++++++++++++++++++ core/src/mm.rs | 4 ++-- core/src/task.rs | 3 ++- src/entry.rs | 4 +++- 8 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 apps/vdso_test/test_getcpu.rs diff --git a/Cargo.lock b/Cargo.lock index 55951aec..4e11ee6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2189,6 +2189,7 @@ dependencies = [ "starry-core", "starry-process", "starry-signal", + "starry-vdso", ] [[package]] @@ -2324,7 +2325,7 @@ dependencies = [ [[package]] name = "starry-vdso" version = "0.1.1" -source = "git+https://github.com/Starry-OS/starry-vdso.git?rev=cf2d4a6#cf2d4a6a2245b0aa8caa15d5faa8cce305f4e9d8" +source = "git+https://github.com/Starry-OS/starry-vdso.git?rev=dab20cc#dab20ccb5d61821810ef2c8b144eccd18a950863" dependencies = [ "axerrno 0.2.2", "axplat 0.2.0", diff --git a/Cargo.toml b/Cargo.toml index fe036a04..f57f7894 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +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 = "cf2d4a6" } +starry-vdso = { git = "https://github.com/Starry-OS/starry-vdso.git", rev = "dab20cc" } starry-core = { path = "./core" } starry-api = { path = "./api" } @@ -128,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/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/src/mm.rs b/core/src/mm.rs index b615c90c..4e98605a 100644 --- a/core/src/mm.rs +++ b/core/src/mm.rs @@ -325,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)?; @@ -392,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();