From 510b1c64b1fbdee998f3e3e4cd9a5ea5520d5bbc Mon Sep 17 00:00:00 2001 From: Weikang Guo Date: Fri, 29 May 2026 09:37:17 +0800 Subject: [PATCH 1/8] refactor: remove misleading irq_stats from kcore The irq_stats module only counted timer callbacks, not actual hardware interrupts. This is inconsistent with Linux /proc/interrupts which shows per-IRQ, per-CPU statistics from the interrupt controller. Remove the module and its usage. The /proc/interrupts node is left as a stub to be replaced with proper per-IRQ statistics from khal. --- core/kcore/src/irq_stats.rs | 19 ------------------- core/kcore/src/lib.rs | 1 - core/kservices/src/lib.rs | 7 +------ fs/filesystems/procfs/src/irq_nodes/root.rs | 18 ++++-------------- 4 files changed, 5 insertions(+), 40 deletions(-) delete mode 100644 core/kcore/src/irq_stats.rs diff --git a/core/kcore/src/irq_stats.rs b/core/kcore/src/irq_stats.rs deleted file mode 100644 index c16117bf0..000000000 --- a/core/kcore/src/irq_stats.rs +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2025 KylinSoft Co., Ltd. -// See LICENSES for license details. - -//! Interrupt statistics shared by kernel services and procfs. - -use core::sync::atomic::{AtomicUsize, Ordering}; - -static IRQ_CNT: AtomicUsize = AtomicUsize::new(0); - -/// Increment the interrupt count (called from timer callback). -pub fn inc_irq_cnt() { - IRQ_CNT.fetch_add(1, Ordering::Relaxed); -} - -/// Get the current interrupt count. -pub fn irq_cnt() -> usize { - IRQ_CNT.load(Ordering::Relaxed) -} diff --git a/core/kcore/src/lib.rs b/core/kcore/src/lib.rs index bd6655853..b9de0215e 100644 --- a/core/kcore/src/lib.rs +++ b/core/kcore/src/lib.rs @@ -15,6 +15,5 @@ extern crate alloc; #[macro_use] extern crate klogger; -pub mod irq_stats; mod lrucache; pub mod mm; diff --git a/core/kservices/src/lib.rs b/core/kservices/src/lib.rs index 0b5853f16..a5fe7f1e9 100644 --- a/core/kservices/src/lib.rs +++ b/core/kservices/src/lib.rs @@ -27,7 +27,7 @@ mod unittest_task; #[cfg(unittest)] pub use unittest_task::{register_unittest_runtime, run_with_test_user_thread}; -/// Initializes VFS, /proc/interrupts accounting, and alarm task. +/// Initializes VFS and alarm task. pub fn init() { info!("Initialize VFS..."); devfs::capture_firmware_dtb_snapshot(); @@ -57,11 +57,6 @@ pub fn init() { warn!("/dev/log not available: {err}"); } - info!("Initialize /proc/interrupts..."); - ktask::register_timer_callback(|_| { - kcore::irq_stats::inc_irq_cnt(); - }); - info!("Initialize alarm..."); kthread::spawn_alarm_task(); } diff --git a/fs/filesystems/procfs/src/irq_nodes/root.rs b/fs/filesystems/procfs/src/irq_nodes/root.rs index 3f31631eb..d7a717b6c 100644 --- a/fs/filesystems/procfs/src/irq_nodes/root.rs +++ b/fs/filesystems/procfs/src/irq_nodes/root.rs @@ -2,20 +2,10 @@ // Copyright 2025 KylinSoft Co., Ltd. // See LICENSES for license details. -use alloc::{borrow::Cow, format, sync::Arc}; +use alloc::sync::Arc; -use kvfs::VfsResult; -use kvfs_simple::{DirMapping, SimpleFile, SimpleFs}; +use kvfs_simple::{DirMapping, SimpleFs}; -fn read_proc_interrupts() -> VfsResult> { - Ok(Cow::Owned( - format!("0: {}\n", kcore::irq_stats::irq_cnt()).into_bytes(), - )) -} - -pub(crate) fn add_root_entries(root: &mut DirMapping, fs: Arc) { - root.add( - "interrupts", - SimpleFile::new_regular(fs, read_proc_interrupts), - ); +pub(crate) fn add_root_entries(_root: &mut DirMapping, _fs: Arc) { + // /proc/interrupts stub — will be replaced with per-IRQ statistics from khal. } -- Gitee From 073113c1d0f41116eed1c58c15244e8b469dff05 Mon Sep 17 00:00:00 2001 From: Weikang Guo Date: Fri, 29 May 2026 09:55:05 +0800 Subject: [PATCH 2/8] refactor: move new_user_aspace_empty into AddrSpace::new_user_empty The helper function only called AddrSpace::new_empty with user-space layout constants from kaddr_layout, which memspace already depends on. Move it to AddrSpace as an inherent method and remove the kcore wrapper. Also drop procfs's unused kcore dependency (leftover from irq_stats removal). --- core/kcore/src/mm.rs | 8 -------- core/kservices/Cargo.toml | 1 + core/kservices/src/unittest_task.rs | 2 +- entry/Cargo.toml | 1 + entry/src/entry.rs | 4 ++-- fs/filesystems/procfs/Cargo.toml | 1 - mm/memspace/src/aspace.rs | 8 ++++++++ 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/core/kcore/src/mm.rs b/core/kcore/src/mm.rs index cbc32a25b..00282dd58 100644 --- a/core/kcore/src/mm.rs +++ b/core/kcore/src/mm.rs @@ -31,14 +31,6 @@ use ouroboros::self_referencing; use crate::lrucache::LruCache; -/// Creates a new empty user address space. -pub fn new_user_aspace_empty() -> KResult { - AddrSpace::new_empty( - VirtAddr::from_usize(kaddr_layout::USER_SPACE_BASE), - kaddr_layout::USER_SPACE_SIZE, - ) -} - /// If the target architecture requires it, the kernel portion of the address /// space will be copied to the user address space. pub fn copy_from_kernel(_aspace: &mut AddrSpace) -> KResult { diff --git a/core/kservices/Cargo.toml b/core/kservices/Cargo.toml index fa7909b88..d1bccce22 100644 --- a/core/kservices/Cargo.toml +++ b/core/kservices/Cargo.toml @@ -60,6 +60,7 @@ ksignal.workspace = true osvm.workspace = true tee_kernel = { workspace = true, optional = true } kcore.workspace = true +memspace.workspace = true posix-ipc.workspace = true procfs.workspace = true devfs.workspace = true diff --git a/core/kservices/src/unittest_task.rs b/core/kservices/src/unittest_task.rs index 94751e697..b26e1e23f 100644 --- a/core/kservices/src/unittest_task.rs +++ b/core/kservices/src/unittest_task.rs @@ -46,7 +46,7 @@ impl InstalledTestThread { let tid = current_task.id().as_u64() as Pid; let pid = alloc_test_process_id(); - let mut aspace = kcore::mm::new_user_aspace_empty()?; + let mut aspace = memspace::AddrSpace::new_user_empty()?; kcore::mm::copy_from_kernel(&mut aspace)?; kcore::mm::map_trampoline(&mut aspace)?; let aspace = Arc::new(Mutex::new(aspace)); diff --git a/entry/Cargo.toml b/entry/Cargo.toml index 3ed980b1a..5a9471165 100644 --- a/entry/Cargo.toml +++ b/entry/Cargo.toml @@ -30,6 +30,7 @@ ksyscall.workspace = true kservices.workspace = true ktty.workspace = true kcore.workspace = true +memspace.workspace = true kbuild_config.workspace = true indoc = "2" backtrace.workspace = true diff --git a/entry/src/entry.rs b/entry/src/entry.rs index 505d611ec..7962b563a 100644 --- a/entry/src/entry.rs +++ b/entry/src/entry.rs @@ -8,7 +8,7 @@ use alloc::{ sync::Arc, }; -use kcore::mm::{copy_from_kernel, load_user_app, new_user_aspace_empty}; +use kcore::mm::{copy_from_kernel, load_user_app}; use kcred::Credentials; use kfs::{kernel_fs_context, new_process_fs_context}; use khal::uspace::UserContext; @@ -21,7 +21,7 @@ use ktty::tty::N_TTY; /// Create and run the init process with the given argv/envp. pub fn run_initproc(args: &[String], envs: &[String]) -> i32 { - let mut uspace = new_user_aspace_empty() + let mut uspace = memspace::AddrSpace::new_user_empty() .and_then(|mut it| { copy_from_kernel(&mut it)?; Ok(it) diff --git a/fs/filesystems/procfs/Cargo.toml b/fs/filesystems/procfs/Cargo.toml index e5fb98640..d70df2172 100644 --- a/fs/filesystems/procfs/Cargo.toml +++ b/fs/filesystems/procfs/Cargo.toml @@ -14,7 +14,6 @@ sysrq = ["ktask/snapshot"] tee = ["kthread/tee", "dep:tee_task_iface"] [dependencies] -kcore.workspace = true kvfs.workspace = true kaddr_layout.workspace = true kalloc.workspace = true diff --git a/mm/memspace/src/aspace.rs b/mm/memspace/src/aspace.rs index 5cbefae90..ab275e22d 100644 --- a/mm/memspace/src/aspace.rs +++ b/mm/memspace/src/aspace.rs @@ -82,6 +82,14 @@ impl AddrSpace { }) } + /// Creates a new empty user address space with the standard user-space range. + pub fn new_user_empty() -> KResult { + Self::new_empty( + VirtAddr::from_usize(kaddr_layout::USER_SPACE_BASE), + kaddr_layout::USER_SPACE_SIZE, + ) + } + /// Copies page table mappings from another address space. /// /// It copies the page table entries only rather than the memory regions, -- Gitee From 527e0aa6a1af69405e73f4af737de624c7a9b602 Mon Sep 17 00:00:00 2001 From: Weikang Guo Date: Fri, 29 May 2026 10:32:19 +0800 Subject: [PATCH 3/8] =?UTF-8?q?rename:=20ktypes=20=E2=86=92=20klazy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The crate provides Once and Lazy — one-time initialization and lazy evaluation primitives. The name 'klazy' accurately reflects this role, while 'ktypes' was misleading (suggesting shared type defs). Cannot merge into ksync due to circular dependency: ksync → khal → kalloc → backtrace → klazy. --- Cargo.toml | 2 +- core/{ktypes => klazy}/Cargo.toml | 2 +- core/{ktypes => klazy}/docs/design.md | 8 ++++---- core/{ktypes => klazy}/docs/security.md | 10 +++++----- core/{ktypes => klazy}/src/lazy.rs | 4 ++-- core/{ktypes => klazy}/src/lib.rs | 0 core/{ktypes => klazy}/src/once.rs | 12 ++++++------ core/ktracing/Cargo.toml | 2 +- core/ktracing/src/lib.rs | 2 +- docs/templates/module-docs-guide.md | 2 +- fs/filesystems/devfs/Cargo.toml | 4 ++-- fs/filesystems/devfs/src/nodes/dice.rs | 2 +- fs/runtime/kfs/Cargo.toml | 2 +- fs/runtime/kfs/src/highlevel/fs.rs | 2 +- platforms/aarch64-crosvm-virt/Cargo.toml | 2 +- platforms/aarch64-crosvm-virt/src/psci.rs | 2 +- platforms/aarch64-peripherals/Cargo.toml | 2 +- platforms/aarch64-peripherals/src/memory.rs | 2 +- platforms/x86-peripherals/Cargo.toml | 2 +- platforms/x86-peripherals/src/bootmem.rs | 2 +- process/kthread/Cargo.toml | 2 +- process/kthread/src/timer_delivery.rs | 2 +- process/ktimer/Cargo.toml | 2 +- process/ktimer/src/runtime.rs | 2 +- tee/tee_kernel/Cargo.toml | 2 +- tee/tee_kernel/src/tee/rng_software.rs | 2 +- tee/tee_kernel/src/tee/tee_svc_storage.rs | 2 +- tee/tee_task_iface/Cargo.toml | 4 ++-- tee/tee_task_iface/src/lib.rs | 2 +- tee/tee_task_iface/src/tasign.rs | 2 +- util/backtrace/Cargo.toml | 2 +- util/backtrace/src/dwarf.rs | 2 +- util/backtrace/src/lib.rs | 2 +- 33 files changed, 47 insertions(+), 47 deletions(-) rename core/{ktypes => klazy}/Cargo.toml (94%) rename core/{ktypes => klazy}/docs/design.md (97%) rename core/{ktypes => klazy}/docs/security.md (97%) rename core/{ktypes => klazy}/src/lazy.rs (99%) rename core/{ktypes => klazy}/src/lib.rs (100%) rename core/{ktypes => klazy}/src/once.rs (99%) diff --git a/Cargo.toml b/Cargo.toml index fc5225558..911e615c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,7 @@ x86_boot_common = { path = "boot/x86-boot-common", package = "x86-boot-common" } # Internal: core runtime and services kcred = { path = "process/kcred" } kruntime = { path = "core/kruntime" } -ktypes = { path = "core/ktypes" } +klazy = { path = "core/klazy" } # Internal: tracing and debugging ktracing = { path = "core/ktracing" } diff --git a/core/ktypes/Cargo.toml b/core/klazy/Cargo.toml similarity index 94% rename from core/ktypes/Cargo.toml rename to core/klazy/Cargo.toml index 8b694d18b..052621dcd 100644 --- a/core/ktypes/Cargo.toml +++ b/core/klazy/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ktypes" +name = "klazy" version.workspace = true edition.workspace = true license.workspace = true diff --git a/core/ktypes/docs/design.md b/core/klazy/docs/design.md similarity index 97% rename from core/ktypes/docs/design.md rename to core/klazy/docs/design.md index 1d5dac49f..a42224c1b 100644 --- a/core/ktypes/docs/design.md +++ b/core/klazy/docs/design.md @@ -1,8 +1,8 @@ -# ktypes — 设计文档 +# klazy — 设计文档 ## 定位 -`ktypes` 提供兼容 `no_std` 的一次性初始化和延迟求值同步原语。这些原语是 +`klazy` 提供兼容 `no_std` 的一次性初始化和延迟求值同步原语。这些原语是 x-kernel 中内核服务静态延迟初始化的基础构件(如 tracing、内存管理、TEE 服务、密码学模块)。 @@ -19,7 +19,7 @@ OS 线程或条件变量。 涉及的源文件: ``` -core/ktypes/ +core/klazy/ ├── src/ │ ├── lib.rs │ ├── once.rs @@ -128,7 +128,7 @@ Lazy ──使用──> Once ### 为什么不用 `spin::Once` -上游 `spin` crate 提供类似功能。我们将设计引入 `ktypes` 是为了: +上游 `spin` crate 提供类似功能。我们将设计引入 `klazy` 是为了: - 控制 API 范围(添加 `try_call_once`、`initialized()` 等)。 - 不受 `spin` 发布节奏影响,确保稳定性。 diff --git a/core/ktypes/docs/security.md b/core/klazy/docs/security.md similarity index 97% rename from core/ktypes/docs/security.md rename to core/klazy/docs/security.md index 13485f648..f557d68ad 100644 --- a/core/ktypes/docs/security.md +++ b/core/klazy/docs/security.md @@ -1,8 +1,8 @@ -# ktypes — 安全与可靠性分析 +# klazy — 安全与可靠性分析 ## 概述 -`ktypes` 是 x-kernel 中广泛使用的底层同步原语,负责内核服务的一次性初始化。 +`klazy` 是 x-kernel 中广泛使用的底层同步原语,负责内核服务的一次性初始化。 其中包含 `unsafe` 代码,涉及内部可变性和原子状态转换。不正确的使用或不变量 破损将导致未定义行为。 @@ -26,7 +26,7 @@ └──────────────────────────────────┘ ``` -- **safe API 调用者**信任 `ktypes` 正确维护其不变量。 +- **safe API 调用者**信任 `klazy` 正确维护其不变量。 - **unsafe API 调用者**(`get_unchecked`、`get_mut_unchecked`、 `into_inner_unchecked`、`as_mut_ptr`)需自行证明初始化已完成。 @@ -149,7 +149,7 @@ core::ptr::drop_in_place((*self.storage.get()).as_mut_ptr()); ## 故障管理 -`ktypes` 通过以下机制处理故障: +`klazy` 通过以下机制处理故障: - **错误传播**:`try_call_once` 返回 `Result<&T, E>`,调用者可处理错误。 - **中毒检测**:所有 `Failed` 状态的访问立即 panic,防止使用不一致状态。 @@ -179,7 +179,7 @@ core::ptr::drop_in_place((*self.storage.get()).as_mut_ptr()); ## 审计清单 -修改 `ktypes` 时需验证: +修改 `klazy` 时需验证: - [ ] 每个 `unsafe` 块均有 `SAFETY:` 注释说明不变量。 - [ ] 新增的 `u8 → Status` 转换不绕过 `AtomicStatus`。 diff --git a/core/ktypes/src/lazy.rs b/core/klazy/src/lazy.rs similarity index 99% rename from core/ktypes/src/lazy.rs rename to core/klazy/src/lazy.rs index 2513d51ea..e1f15ebfc 100644 --- a/core/ktypes/src/lazy.rs +++ b/core/klazy/src/lazy.rs @@ -35,7 +35,7 @@ use crate::once::Once; /// ``` /// use std::collections::HashMap; /// -/// use ktypes::Lazy; +/// use klazy::Lazy; /// /// static HASHMAP: Lazy> = Lazy::new(|| { /// println!("initializing"); @@ -120,7 +120,7 @@ impl T> Lazy { /// # Examples /// /// ``` - /// use ktypes::Lazy; + /// use klazy::Lazy; /// /// let lazy = Lazy::new(|| 92); /// diff --git a/core/ktypes/src/lib.rs b/core/klazy/src/lib.rs similarity index 100% rename from core/ktypes/src/lib.rs rename to core/klazy/src/lib.rs diff --git a/core/ktypes/src/once.rs b/core/klazy/src/once.rs similarity index 99% rename from core/ktypes/src/once.rs rename to core/klazy/src/once.rs index 4a5a237de..acbd320d9 100644 --- a/core/ktypes/src/once.rs +++ b/core/klazy/src/once.rs @@ -37,9 +37,9 @@ use core::{ /// # Examples /// /// ``` -/// use ktypes; +/// use klazy; /// -/// static START: ktypes::Once = ktypes::Once::new(); +/// static START: klazy::Once = klazy::Once::new(); /// /// START.call_once(|| { /// // run initialization here @@ -180,9 +180,9 @@ impl Once { /// # Examples /// /// ``` - /// use ktypes; + /// use klazy; /// - /// static INIT: ktypes::Once = ktypes::Once::new(); + /// static INIT: klazy::Once = klazy::Once::new(); /// /// fn get_cached_val() -> usize { /// *INIT.call_once(expensive_computation) @@ -220,9 +220,9 @@ impl Once { /// # Examples /// /// ``` - /// use ktypes; + /// use klazy; /// - /// static INIT: ktypes::Once = ktypes::Once::new(); + /// static INIT: klazy::Once = klazy::Once::new(); /// /// fn get_cached_val() -> Result { /// INIT.try_call_once(expensive_fallible_computation) diff --git a/core/ktracing/Cargo.toml b/core/ktracing/Cargo.toml index cf8f683f9..62848b398 100644 --- a/core/ktracing/Cargo.toml +++ b/core/ktracing/Cargo.toml @@ -19,7 +19,7 @@ karch = { workspace = true } khal = { workspace = true } static-keys = { workspace = true } kspin = { workspace = true } -ktypes = { workspace = true } +klazy = { workspace = true } lock_api = { workspace = true } memspace = { workspace = true } memaddr = { workspace = true } diff --git a/core/ktracing/src/lib.rs b/core/ktracing/src/lib.rs index 430843529..1d2d1f4ee 100644 --- a/core/ktracing/src/lib.rs +++ b/core/ktracing/src/lib.rs @@ -13,13 +13,13 @@ use alloc::{ use core::mem; use khal::paging::MappingFlags; +use klazy::Once; use kspin::{SpinNoIrq, SpinRaw}; use ktask::current; use ktracepoint::{ KernelTraceOps, TraceCmdLineCache, TraceEntryParser, TracePipeOps, TracePipeRaw, TracingEventsManager, global_init_events, }; -use ktypes::Once; use memaddr::{PAGE_SIZE_4K, VirtAddr}; static TRACE_RAW_PIPE: SpinNoIrq = SpinNoIrq::new(TracePipeRaw::new(4096)); diff --git a/docs/templates/module-docs-guide.md b/docs/templates/module-docs-guide.md index 22ade46ff..37d0d3174 100644 --- a/docs/templates/module-docs-guide.md +++ b/docs/templates/module-docs-guide.md @@ -8,7 +8,7 @@ 每个 crate 在自身目录下维护 `docs/`: ``` -core/ktypes/ +core/klazy/ ├── src/ │ ├── lib.rs # rustdoc — 函数说明、接口语义、unsafe contract │ ├── once.rs diff --git a/fs/filesystems/devfs/Cargo.toml b/fs/filesystems/devfs/Cargo.toml index b47f91bd9..dc796cb35 100644 --- a/fs/filesystems/devfs/Cargo.toml +++ b/fs/filesystems/devfs/Cargo.toml @@ -13,7 +13,7 @@ documentation.workspace = true input = ["dep:inputdev"] memtrack = ["kalloc/tracking", "dep:gimli"] dev-log = [] -dice = ["dep:dice_driver", "dep:ktypes", "dep:rand_chacha", "dep:mbedtls"] +dice = ["dep:dice_driver", "dep:klazy", "dep:rand_chacha", "dep:mbedtls"] [dependencies] kalloc.workspace = true @@ -51,7 +51,7 @@ backtrace.workspace = true gimli = { version = "*", default-features = false, optional = true } dice_driver = { workspace = true, optional = true } inputdev = { workspace = true, optional = true } -ktypes = { workspace = true, optional = true } +klazy = { workspace = true, optional = true } rand_chacha = { version = "0.3", default-features = false, optional = true } mbedtls = { workspace = true, optional = true } unittest.workspace = true diff --git a/fs/filesystems/devfs/src/nodes/dice.rs b/fs/filesystems/devfs/src/nodes/dice.rs index ea9d76223..9161e1a80 100644 --- a/fs/filesystems/devfs/src/nodes/dice.rs +++ b/fs/filesystems/devfs/src/nodes/dice.rs @@ -8,8 +8,8 @@ use core::any::Any; use dice_driver::{DICE_IOCTL_GET_HANDOVER, DICE_IOCTL_GET_RAW_HANDOVER}; use kerrno::{KError, KResult}; +use klazy::Lazy; use ksync::Mutex; -use ktypes::Lazy; use kvfs::DeviceFileOps; use kvfs_simple::{DirMapping, SimpleFs}; use osvm::{VirtMutPtr, VirtPtr, write_vm_mem}; diff --git a/fs/runtime/kfs/Cargo.toml b/fs/runtime/kfs/Cargo.toml index c3909dd53..9db200a03 100644 --- a/fs/runtime/kfs/Cargo.toml +++ b/fs/runtime/kfs/Cargo.toml @@ -43,7 +43,7 @@ log = { workspace = true } lru = "0.16.0" slab = { version = "0.4.9", default-features = false } unittest = { workspace = true } -ktypes = { workspace = true } +klazy = { workspace = true } fs9p = { workspace = true, optional = true } rsext4 = { workspace = true, optional = true } diff --git a/fs/runtime/kfs/src/highlevel/fs.rs b/fs/runtime/kfs/src/highlevel/fs.rs index 6ffbc6d5b..f02356b3a 100644 --- a/fs/runtime/kfs/src/highlevel/fs.rs +++ b/fs/runtime/kfs/src/highlevel/fs.rs @@ -11,8 +11,8 @@ use alloc::{ vec::Vec, }; +use klazy::Once; use ksync::Mutex; -use ktypes::Once; use kvfs::{ Location, Metadata, NodePermission, NodeType, VfsError, VfsResult, path::{Path, PathBuf}, diff --git a/platforms/aarch64-crosvm-virt/Cargo.toml b/platforms/aarch64-crosvm-virt/Cargo.toml index 47622c3b3..12e744a33 100644 --- a/platforms/aarch64-crosvm-virt/Cargo.toml +++ b/platforms/aarch64-crosvm-virt/Cargo.toml @@ -25,7 +25,7 @@ console_driver = { workspace = true, features = ["ns16550-mmio"] } irq_driver = { workspace = true } khal = { workspace = true } kbuild_config = { workspace = true } -ktypes = { workspace = true } +klazy = { workspace = true } kerrno = { workspace = true } rtc_driver = { workspace = true } timer_driver = { workspace = true } diff --git a/platforms/aarch64-crosvm-virt/src/psci.rs b/platforms/aarch64-crosvm-virt/src/psci.rs index 2be8fbaa0..d29d8a423 100644 --- a/platforms/aarch64-crosvm-virt/src/psci.rs +++ b/platforms/aarch64-crosvm-virt/src/psci.rs @@ -3,8 +3,8 @@ // See LICENSES for license details. //! PSCI wrappers and KVM guard-granule helpers. +use klazy::Once; use kplat::{dma::PlatformDmaIf, mmio::PlatformMmioIf}; -use ktypes::Once; pub static GUARD_GRANULE: Once = Once::new(); const ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID: u32 = ((1) << 31) | ((1) << 30) | (((6) & 0x3F) << 24) | ((4) & 0xFFFF); diff --git a/platforms/aarch64-peripherals/Cargo.toml b/platforms/aarch64-peripherals/Cargo.toml index 6c862cff0..ae44210c4 100644 --- a/platforms/aarch64-peripherals/Cargo.toml +++ b/platforms/aarch64-peripherals/Cargo.toml @@ -17,7 +17,7 @@ nmi-sdei = [] [dependencies] memaddr = { workspace = true } -ktypes = { workspace = true } +klazy = { workspace = true } kcpu_id_map = { workspace = true } log = "0.4" lazyinit = "0.2" diff --git a/platforms/aarch64-peripherals/src/memory.rs b/platforms/aarch64-peripherals/src/memory.rs index 11862c029..df4e75ba5 100644 --- a/platforms/aarch64-peripherals/src/memory.rs +++ b/platforms/aarch64-peripherals/src/memory.rs @@ -10,7 +10,7 @@ use heapless::Vec; use khal::mem::{ MemRange, PhysAddr, ReservedKind, ReservedRegion, ReservedSource, VirtAddr, sub_ranges, }; -use ktypes::Once; +use klazy::Once; use memaddr::MemoryAddr; use of::{dtb_total_size_from_ptr, read_memory_regions, read_reserved_memory_regions}; diff --git a/platforms/x86-peripherals/Cargo.toml b/platforms/x86-peripherals/Cargo.toml index 64b690f1e..5236d3c1a 100644 --- a/platforms/x86-peripherals/Cargo.toml +++ b/platforms/x86-peripherals/Cargo.toml @@ -10,7 +10,7 @@ repository.workspace = true [dependencies] log = "0.4" -ktypes = { workspace = true } +klazy = { workspace = true } kcpu_id_map = { workspace = true } khal = { workspace = true } kbuild_config = { workspace = true } diff --git a/platforms/x86-peripherals/src/bootmem.rs b/platforms/x86-peripherals/src/bootmem.rs index 4ab6c4776..166b1441f 100644 --- a/platforms/x86-peripherals/src/bootmem.rs +++ b/platforms/x86-peripherals/src/bootmem.rs @@ -6,7 +6,7 @@ use core::{mem, ptr}; use boot_info::{BootInfo, BootProtocol, LinuxBootParams, X86LinuxE820EntryType}; use khal::mem::ReservedKind; -use ktypes::Once; +use klazy::Once; use multiboot2::{BootInformation, BootInformationHeader, MemoryAreaType}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/process/kthread/Cargo.toml b/process/kthread/Cargo.toml index df22aed2b..84ae29727 100644 --- a/process/kthread/Cargo.toml +++ b/process/kthread/Cargo.toml @@ -30,7 +30,7 @@ ksignal.workspace = true ksync.workspace = true ktask.workspace = true ktimer.workspace = true -ktypes.workspace = true +klazy.workspace = true lazy_static.workspace = true memspace.workspace = true slab.workspace = true diff --git a/process/kthread/src/timer_delivery.rs b/process/kthread/src/timer_delivery.rs index e54b11cda..6dc7e0f01 100644 --- a/process/kthread/src/timer_delivery.rs +++ b/process/kthread/src/timer_delivery.rs @@ -10,10 +10,10 @@ use alloc::vec::Vec; +use klazy::Once; use kprocess::Pid; use ksignal::{SignalDequeueAction, SignalInfo, Signo}; use ktimer::{TimerDelivery, TimerSignal}; -use ktypes::Once; use crate::{ get_process_state, diff --git a/process/ktimer/Cargo.toml b/process/ktimer/Cargo.toml index 6864ecff9..b535c6ea3 100644 --- a/process/ktimer/Cargo.toml +++ b/process/ktimer/Cargo.toml @@ -18,7 +18,7 @@ kprocess.workspace = true ksignal.workspace = true ksync.workspace = true ktask.workspace = true -ktypes.workspace = true +klazy.workspace = true linux-raw-sys = { workspace = true, default-features = false, features = ["general", "no_std"] } posix-types.workspace = true unittest.workspace = true diff --git a/process/ktimer/src/runtime.rs b/process/ktimer/src/runtime.rs index ed3ab05fa..a33993bef 100644 --- a/process/ktimer/src/runtime.rs +++ b/process/ktimer/src/runtime.rs @@ -16,10 +16,10 @@ use core::{cmp::Ordering, time::Duration}; use event_listener::{Event, listener}; use khal::time::monotonic_time; +use klazy::Once; use kprocess::Pid; use ksync::Mutex; use ktask::future::{block_on, timeout_at}; -use ktypes::Once; struct Entry { deadline: Duration, diff --git a/tee/tee_kernel/Cargo.toml b/tee/tee_kernel/Cargo.toml index b4140a045..3a37b433b 100644 --- a/tee/tee_kernel/Cargo.toml +++ b/tee/tee_kernel/Cargo.toml @@ -25,7 +25,7 @@ unittest_support.workspace = true rust-dice = { workspace = true, optional = true } mbedtls = { workspace = true } mbedtls-sys-auto = { workspace = true } -ktypes.workspace = true +klazy.workspace = true kcpu = { workspace = true, optional = true } dice_driver = { workspace = true, optional = true } kerrno.workspace = true diff --git a/tee/tee_kernel/src/tee/rng_software.rs b/tee/tee_kernel/src/tee/rng_software.rs index 91adad486..53c053bd4 100644 --- a/tee/tee_kernel/src/tee/rng_software.rs +++ b/tee/tee_kernel/src/tee/rng_software.rs @@ -2,8 +2,8 @@ // Copyright 2025 KylinSoft Co., Ltd. // See LICENSES for license details. +use klazy::Lazy; use ksync::Mutex; -use ktypes::Lazy; use mbedtls::{pk::Pk, rng::RngCallback}; use mbedtls_sys_auto::types::{ raw_types::{c_int, c_uchar, c_void}, diff --git a/tee/tee_kernel/src/tee/tee_svc_storage.rs b/tee/tee_kernel/src/tee/tee_svc_storage.rs index b0c61f709..6332672d4 100644 --- a/tee/tee_kernel/src/tee/tee_svc_storage.rs +++ b/tee/tee_kernel/src/tee/tee_svc_storage.rs @@ -10,8 +10,8 @@ use core::{ }; use bytemuck::{Pod, Zeroable, bytes_of, bytes_of_mut}; +use klazy::Once; use ksync::{Mutex, RwLock}; -use ktypes::Once; use tee_raw_sys::*; use super::{ diff --git a/tee/tee_task_iface/Cargo.toml b/tee/tee_task_iface/Cargo.toml index 79e08d5eb..e44a7c5af 100644 --- a/tee/tee_task_iface/Cargo.toml +++ b/tee/tee_task_iface/Cargo.toml @@ -16,7 +16,7 @@ default = [] # TA ELF `.ta_signature` verification at load time; see `src/tasign.rs` and crate `lib.rs` docs. tee_ta_sign = [ "dep:ksync", - "dep:ktypes", + "dep:klazy", "dep:tasign", "dep:tasign_kernel_shim", ] @@ -34,7 +34,7 @@ kfs.workspace = true xmas-elf = { version = "0.9", default-features = false } log.workspace = true ksync = { workspace = true, optional = true } -ktypes = { workspace = true, optional = true } +klazy = { workspace = true, optional = true } tasign = { workspace = true, optional = true, features = ["kernel-verify"] } tasign_kernel_shim = { workspace = true, optional = true } tee_raw_sys.workspace = true diff --git a/tee/tee_task_iface/src/lib.rs b/tee/tee_task_iface/src/lib.rs index 4c16c7bc8..7f760acf4 100644 --- a/tee/tee_task_iface/src/lib.rs +++ b/tee/tee_task_iface/src/lib.rs @@ -7,7 +7,7 @@ //! # Cargo features //! //! - **`tee_ta_sign`** — Enables the `tasign` submodule (TA ELF signature verification), -//! pulls in `tasign` / `ksync` / `ktypes`, and links `tasign-kernel-shim` for mbedTLS +//! pulls in `tasign` / `ksync` / `klazy`, and links `tasign-kernel-shim` for mbedTLS //! libc shims on bare-metal. Without this feature, `tasign` is not compiled; `.ta_head` can //! still be read via [`ta_ctx::read_ta_head_if_applicable`]. //! - **`ta_verify_with_root`** — Uses an embedded CA PEM to verify certificate chain during diff --git a/tee/tee_task_iface/src/tasign.rs b/tee/tee_task_iface/src/tasign.rs index 13f4b51a8..974814710 100644 --- a/tee/tee_task_iface/src/tasign.rs +++ b/tee/tee_task_iface/src/tasign.rs @@ -10,8 +10,8 @@ use core::convert::AsRef; use hashbrown::HashMap; use kerrno::{KError, KResult}; use kfs::{CachedFile, kernel_fs_context}; +use klazy::Lazy; use ksync::Mutex; -use ktypes::Lazy; use log::{error, info}; use crate::ta_ctx::{self, TeeTaCtx}; diff --git a/util/backtrace/Cargo.toml b/util/backtrace/Cargo.toml index 01406f1ac..a0ee84273 100644 --- a/util/backtrace/Cargo.toml +++ b/util/backtrace/Cargo.toml @@ -16,7 +16,7 @@ dwarf = ["dep:addr2line", "dep:gimli", "dep:paste"] [dependencies] cfg-if = { workspace = true } log = { workspace = true } -ktypes.workspace= true +klazy.workspace= true addr2line = { version = "0.25.1", default-features = false, optional = true, features = [ "cpp_demangle", diff --git a/util/backtrace/src/dwarf.rs b/util/backtrace/src/dwarf.rs index c2a459682..24ed25c7e 100644 --- a/util/backtrace/src/dwarf.rs +++ b/util/backtrace/src/dwarf.rs @@ -6,7 +6,7 @@ use alloc::borrow::Cow; use core::{fmt, slice}; use addr2line::Context; -use ktypes::Once; +use klazy::Once; // Only import in non-test builds #[cfg(not(test))] use log::{error, info, warn}; diff --git a/util/backtrace/src/lib.rs b/util/backtrace/src/lib.rs index cb2e96131..f43719b3e 100644 --- a/util/backtrace/src/lib.rs +++ b/util/backtrace/src/lib.rs @@ -38,7 +38,7 @@ extern crate alloc; use alloc::vec::Vec; use core::{fmt, ops::Range}; -use ktypes::Once; +use klazy::Once; // Modules pub mod arch; -- Gitee From 20f93f7f7dc7e460c14980f7e12065c472bf59f4 Mon Sep 17 00:00:00 2001 From: Weikang Guo Date: Fri, 29 May 2026 10:35:54 +0800 Subject: [PATCH 4/8] move: relocate klazy from core/ to util/ klazy is a zero-dependency primitive, not a core service. Placing it alongside kerrno, klogger, and backtrace in util/ better reflects its role. --- Cargo.toml | 2 +- docs/templates/module-docs-guide.md | 2 +- {core => util}/klazy/Cargo.toml | 0 {core => util}/klazy/docs/design.md | 0 {core => util}/klazy/docs/security.md | 0 {core => util}/klazy/src/lazy.rs | 0 {core => util}/klazy/src/lib.rs | 0 {core => util}/klazy/src/once.rs | 0 8 files changed, 2 insertions(+), 2 deletions(-) rename {core => util}/klazy/Cargo.toml (100%) rename {core => util}/klazy/docs/design.md (100%) rename {core => util}/klazy/docs/security.md (100%) rename {core => util}/klazy/src/lazy.rs (100%) rename {core => util}/klazy/src/lib.rs (100%) rename {core => util}/klazy/src/once.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index 911e615c2..a8eaadd0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,7 @@ x86_boot_common = { path = "boot/x86-boot-common", package = "x86-boot-common" } # Internal: core runtime and services kcred = { path = "process/kcred" } kruntime = { path = "core/kruntime" } -klazy = { path = "core/klazy" } +klazy = { path = "util/klazy" } # Internal: tracing and debugging ktracing = { path = "core/ktracing" } diff --git a/docs/templates/module-docs-guide.md b/docs/templates/module-docs-guide.md index 37d0d3174..1efee9256 100644 --- a/docs/templates/module-docs-guide.md +++ b/docs/templates/module-docs-guide.md @@ -8,7 +8,7 @@ 每个 crate 在自身目录下维护 `docs/`: ``` -core/klazy/ +util/klazy/ ├── src/ │ ├── lib.rs # rustdoc — 函数说明、接口语义、unsafe contract │ ├── once.rs diff --git a/core/klazy/Cargo.toml b/util/klazy/Cargo.toml similarity index 100% rename from core/klazy/Cargo.toml rename to util/klazy/Cargo.toml diff --git a/core/klazy/docs/design.md b/util/klazy/docs/design.md similarity index 100% rename from core/klazy/docs/design.md rename to util/klazy/docs/design.md diff --git a/core/klazy/docs/security.md b/util/klazy/docs/security.md similarity index 100% rename from core/klazy/docs/security.md rename to util/klazy/docs/security.md diff --git a/core/klazy/src/lazy.rs b/util/klazy/src/lazy.rs similarity index 100% rename from core/klazy/src/lazy.rs rename to util/klazy/src/lazy.rs diff --git a/core/klazy/src/lib.rs b/util/klazy/src/lib.rs similarity index 100% rename from core/klazy/src/lib.rs rename to util/klazy/src/lib.rs diff --git a/core/klazy/src/once.rs b/util/klazy/src/once.rs similarity index 100% rename from core/klazy/src/once.rs rename to util/klazy/src/once.rs -- Gitee From 430e5685423b92b1aa0624c7f152cc3b1a88b8c1 Mon Sep 17 00:00:00 2001 From: Weikang Guo Date: Fri, 29 May 2026 11:28:44 +0800 Subject: [PATCH 5/8] refactor kcore mm Signed-off-by: Weikang Guo --- core/kcore/Cargo.toml | 3 --- core/kcore/src/mm.rs | 13 ------------- core/kservices/src/unittest_task.rs | 1 - core/ksyscall/src/task/clone.rs | 5 +---- entry/src/entry.rs | 10 +++------- mm/memspace/Cargo.toml | 3 +-- mm/memspace/src/aspace.rs | 22 +++++++++++++++++++--- 7 files changed, 24 insertions(+), 33 deletions(-) diff --git a/core/kcore/Cargo.toml b/core/kcore/Cargo.toml index 946cce105..0444de0fb 100644 --- a/core/kcore/Cargo.toml +++ b/core/kcore/Cargo.toml @@ -41,9 +41,6 @@ unittest.workspace = true kbuild_config = { workspace = true } tee_task_iface = { workspace = true, optional = true } -[target.'cfg(not(any(target_arch = "aarch64", target_arch = "loongarch64")))'.dependencies] -memspace = { workspace = true, features = ["copy"] } - [features] tee = ["dep:tee_task_iface", "kthread/tee"] tee_ta_sign = ["tee_task_iface/tee_ta_sign"] diff --git a/core/kcore/src/mm.rs b/core/kcore/src/mm.rs index 00282dd58..18b550576 100644 --- a/core/kcore/src/mm.rs +++ b/core/kcore/src/mm.rs @@ -31,19 +31,6 @@ use ouroboros::self_referencing; use crate::lrucache::LruCache; -/// If the target architecture requires it, the kernel portion of the address -/// space will be copied to the user address space. -pub fn copy_from_kernel(_aspace: &mut AddrSpace) -> KResult { - #[cfg(not(any(target_arch = "aarch64", target_arch = "loongarch64")))] - { - // ARMv8 (aarch64) and LoongArch64 use separate page tables for user space - // (aarch64: TTBR0_EL1, LoongArch64: PGDL), so there is no need to copy the - // kernel portion to the user page table. - _aspace.copy_mappings_from(&memspace::kernel_layout().lock())?; - } - Ok(()) -} - /// Map the signal trampoline to the user address space. pub fn map_trampoline(aspace: &mut AddrSpace) -> KResult { let signal_trampoline_paddr = v2p(ksignal::arch::signal_trampoline_address().into()); diff --git a/core/kservices/src/unittest_task.rs b/core/kservices/src/unittest_task.rs index b26e1e23f..679686e19 100644 --- a/core/kservices/src/unittest_task.rs +++ b/core/kservices/src/unittest_task.rs @@ -47,7 +47,6 @@ impl InstalledTestThread { let pid = alloc_test_process_id(); let mut aspace = memspace::AddrSpace::new_user_empty()?; - kcore::mm::copy_from_kernel(&mut aspace)?; kcore::mm::map_trampoline(&mut aspace)?; let aspace = Arc::new(Mutex::new(aspace)); diff --git a/core/ksyscall/src/task/clone.rs b/core/ksyscall/src/task/clone.rs index 125916648..8a151a199 100644 --- a/core/ksyscall/src/task/clone.rs +++ b/core/ksyscall/src/task/clone.rs @@ -14,7 +14,6 @@ use alloc::sync::Arc; use bitflags::bitflags; -use kcore::mm::copy_from_kernel; use kerrno::{KError, KResult}; use kfd::{FdTable, FileLike}; use khal::uspace::UserContext; @@ -250,9 +249,7 @@ impl CloneRequest { old_proc_data.address_space().clone() } else { let mut aspace = old_proc_data.address_space().lock(); - let aspace = aspace.try_clone()?; - copy_from_kernel(&mut aspace.lock())?; - aspace + aspace.try_clone()? }; new_task .ctx_mut() diff --git a/entry/src/entry.rs b/entry/src/entry.rs index 7962b563a..bc1fc9117 100644 --- a/entry/src/entry.rs +++ b/entry/src/entry.rs @@ -8,7 +8,7 @@ use alloc::{ sync::Arc, }; -use kcore::mm::{copy_from_kernel, load_user_app}; +use kcore::mm::load_user_app; use kcred::Credentials; use kfs::{kernel_fs_context, new_process_fs_context}; use khal::uspace::UserContext; @@ -21,12 +21,8 @@ use ktty::tty::N_TTY; /// Create and run the init process with the given argv/envp. pub fn run_initproc(args: &[String], envs: &[String]) -> i32 { - let mut uspace = memspace::AddrSpace::new_user_empty() - .and_then(|mut it| { - copy_from_kernel(&mut it)?; - Ok(it) - }) - .expect("Failed to create user address space"); + let mut uspace = + memspace::AddrSpace::new_user_empty().expect("Failed to create user address space"); let loc = kernel_fs_context() .lock() diff --git a/mm/memspace/Cargo.toml b/mm/memspace/Cargo.toml index 5d126b420..7020556be 100644 --- a/mm/memspace/Cargo.toml +++ b/mm/memspace/Cargo.toml @@ -8,7 +8,6 @@ homepage.workspace = true [features] default = [] -copy = ["page_table/copy-from"] smp = ["page_table/smp"] [dependencies] @@ -22,7 +21,7 @@ lazyinit = { workspace = true } log = { workspace = true } memaddr = { workspace = true } memset = { workspace = true } -page_table = { workspace = true } +page_table = { workspace = true, features = ["copy-from"]} unittest.workspace = true kbuild_config = { workspace = true } karch = { workspace = true } diff --git a/mm/memspace/src/aspace.rs b/mm/memspace/src/aspace.rs index ab275e22d..be44aee35 100644 --- a/mm/memspace/src/aspace.rs +++ b/mm/memspace/src/aspace.rs @@ -84,10 +84,12 @@ impl AddrSpace { /// Creates a new empty user address space with the standard user-space range. pub fn new_user_empty() -> KResult { - Self::new_empty( + let mut aspace = Self::new_empty( VirtAddr::from_usize(kaddr_layout::USER_SPACE_BASE), kaddr_layout::USER_SPACE_SIZE, - ) + )?; + aspace.copy_kernel_mappings()?; + Ok(aspace) } /// Copies page table mappings from another address space. @@ -97,7 +99,6 @@ impl AddrSpace { /// user space. /// /// Returns an error if the two address spaces overlap. - #[cfg(feature = "copy")] pub fn copy_mappings_from(&mut self, other: &AddrSpace) -> KResult { self.pgtbl .modify() @@ -105,6 +106,20 @@ impl AddrSpace { Ok(()) } + /// If the target architecture requires it, copies the kernel portion + /// of the address space to this address space. + /// + /// On aarch64 and loongarch64, user space uses separate page tables + /// (TTBR0_EL1 / PGDL), so no copy is needed. On other architectures + /// the kernel mappings are shared by copying page table entries. + fn copy_kernel_mappings(&mut self) -> KResult { + #[cfg(not(any(target_arch = "aarch64", target_arch = "loongarch64")))] + { + self.copy_mappings_from(&memspace::kernel_layout().lock())?; + } + Ok(()) + } + fn validate_region(&self, start: VirtAddr, size: usize) -> KResult { if !self.contains_range(start, size) { k_bail!(NoMemory, "address out of range"); @@ -474,6 +489,7 @@ impl AddrSpace { let new_aspace_clone = new_aspace.clone(); let mut guard = new_aspace.lock(); + guard.copy_kernel_mappings()?; let mut self_modify = self.pgtbl.modify(); for area in self.areas.iter() { -- Gitee From 4d2dba950a998cdc0f120539acbd59a3fe7a12ea Mon Sep 17 00:00:00 2001 From: Weikang Guo Date: Fri, 29 May 2026 16:10:44 +0800 Subject: [PATCH 6/8] remove kservices Signed-off-by: Weikang Guo --- AGENTS.md | 74 +++ Cargo.toml | 3 +- api/kfeat/Cargo.toml | 6 +- core/kservices/Cargo.toml | 1 - core/kservices/src/unittest_task.rs | 2 +- core/kservices/src/vfs/tmp.rs | 477 ------------------ core/ksyscall/Cargo.toml | 2 +- core/ksyscall/src/task/execve.rs | 2 +- core/kuaccess/Cargo.toml | 21 + core/kuaccess/src/lib.rs | 148 ++++++ entry/Cargo.toml | 3 +- entry/src/entry.rs | 2 +- entry/src/main.rs | 1 + fs/filesystems/devfs/Cargo.toml | 2 +- fs/filesystems/devfs/src/nodes/memtrack.rs | 6 +- {core/kcore => process/kexec}/Cargo.toml | 42 +- {core/kcore => process/kexec}/src/lib.rs | 10 +- .../src/mm.rs => process/kexec/src/loader.rs | 201 ++------ .../kexec/src/lru_cache.rs | 35 +- process/ksignal/Cargo.toml | 4 + process/ksignal/src/lib.rs | 3 + process/ksignal/src/trampoline.rs | 22 + 22 files changed, 357 insertions(+), 710 deletions(-) create mode 100644 AGENTS.md delete mode 100644 core/kservices/src/vfs/tmp.rs create mode 100644 core/kuaccess/Cargo.toml create mode 100644 core/kuaccess/src/lib.rs rename {core/kcore => process/kexec}/Cargo.toml (63%) rename {core/kcore => process/kexec}/src/lib.rs (64%) rename core/kcore/src/mm.rs => process/kexec/src/loader.rs (65%) rename core/kcore/src/lrucache.rs => process/kexec/src/lru_cache.rs (86%) create mode 100644 process/ksignal/src/trampoline.rs diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..4bf039fb7 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,74 @@ +# X-Kernel Agent Notes + +## Project Overview + +X-Kernel is a multi-architecture Rust OS/kernel project. + +Major areas: + +- `arch/`: architecture HAL and CPU support. +- `boot/`: boot protocol handoff, boot stubs, and loaders. +- `core/`: core runtime, syscall, tracing, and services. +- `mm/`: memory management and address-space abstractions. +- `drivers/`: shared hardware drivers and device subsystems. +- `platforms/`: platform glue and defconfigs. +- `process/`, `task/`, `fs/`, `io/`, `net/`, and `tee/`: subsystem crates. +- `util/`: shared utility crates such as `klazy`. + +## Current Refactor Context + +Recent work removed the old catch-all `kcore` crate and tightened subsystem +ownership boundaries. + +- Move reusable utility crates out of `core/` into `util/`. +- Keep address-space logic inside `mm/memspace`. +- Keep kernel user-memory access glue in `core/kuaccess`. +- Keep user program loading and exec image setup in `process/kexec`. +- Avoid reintroducing broad catch-all crates for responsibilities owned by + `memspace`, `kuaccess`, or `kexec`. +- Prefer shared driver, HAL, and memory-management layers over platform-local + forks. +- Keep refactoring commits separate from feature or behavior commits. + +## Build And Validation + +Always prepare `.config` from a platform defconfig before build, run, or +QEMU-based unit-test commands. + +```bash +cp platforms/aarch64-qemu-virt/defconfig .config +make defconfig +``` + +Common commands: + +```bash +make build +make clippy +make run +make UNITTEST=y run +make unittest +cargo +nightly-2026-03-08 fmt --all +``` + +Do not use bare `cargo check -p ` as the main validation path. +The project relies on Kconfig-generated features and `.cargo/.xconfig.toml`, +so prefer the Makefile/Kconfig flow. + +The current checked-in toolchain is described by `rust-toolchain.toml`. + +## Coding Guidelines + +Read `.claude/skills/asterinas-coding-guidelines/SKILL.md` before writing or +reviewing Rust kernel code. + +Key local rules: + +- Use accurate, descriptive names and encode units where the type does not. +- Keep boolean names assertion-like, such as `is_*`, `has_*`, or `can_*`. +- Comments should explain why, not restate what the code does. +- Every `unsafe` block needs a preceding `SAFETY:` justification. +- Validate at subsystem boundaries and trust validated internal invariants. +- Use `?` for ordinary error propagation. +- Avoid casual atomics and linear scans on hot paths. +- Use workspace dependencies and existing local helper APIs where available. diff --git a/Cargo.toml b/Cargo.toml index a8eaadd0b..4a8a078a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,6 @@ categories = ["os", "no-std"] [workspace.dependencies] # Internal: API and core services -kcore = { path = "core/kcore" } kfeat = { path = "api/kfeat" } kservices = { path = "core/kservices" } ksignal = { path = "process/ksignal" } @@ -59,6 +58,7 @@ klazy = { path = "util/klazy" } # Internal: tracing and debugging ktracing = { path = "core/ktracing" } kbpf = { path = "core/kbpf" } +kuaccess = { path = "core/kuaccess" } # Internal: task scheduling and synchronization kpoll = { path = "task/kpoll" } @@ -70,6 +70,7 @@ ksched = { path = "task/ksched" } # Internal: process management kfutex = { path = "process/kfutex" } kfd = { path = "process/kfd" } +kexec = { path = "process/kexec" } krlimit = { path = "process/krlimit" } kresources = { path = "process/kresources" } kthread = { path = "process/kthread" } diff --git a/api/kfeat/Cargo.toml b/api/kfeat/Cargo.toml index fde307619..e014fa9d3 100644 --- a/api/kfeat/Cargo.toml +++ b/api/kfeat/Cargo.toml @@ -150,11 +150,11 @@ watchdog_hardlockup = [ tee = [ "dep:tee_kernel", "dep:tee_task_iface", - "kcore/tee", + "kexec/tee", "ksyscall/tee", "kservices/tee", ] -tee_ta_sign = ["kcore/tee_ta_sign", "ksyscall/tee_ta_sign", "tee_task_iface/tee_ta_sign"] +tee_ta_sign = ["kexec/tee_ta_sign", "ksyscall/tee_ta_sign", "tee_task_iface/tee_ta_sign"] csv_huk_key = ["tee_kernel/csv_huk_key"] virtcca_huk_key = ["tee_kernel/virtcca_huk_key"] ta_verify_with_root = ["tee_ta_sign", "tee_task_iface/ta_verify_with_root"] @@ -195,7 +195,7 @@ loongarch64-qemu-virt = { workspace = true, optional = true, features = [ "fp-simd", "rtc", ] } -kcore = { workspace = true } +kexec = { workspace = true } devfs = { workspace = true } kfs = { workspace = true, optional = true } khal.workspace = true diff --git a/core/kservices/Cargo.toml b/core/kservices/Cargo.toml index d1bccce22..af87ccd72 100644 --- a/core/kservices/Cargo.toml +++ b/core/kservices/Cargo.toml @@ -59,7 +59,6 @@ kthread.workspace = true ksignal.workspace = true osvm.workspace = true tee_kernel = { workspace = true, optional = true } -kcore.workspace = true memspace.workspace = true posix-ipc.workspace = true procfs.workspace = true diff --git a/core/kservices/src/unittest_task.rs b/core/kservices/src/unittest_task.rs index 679686e19..de294b50b 100644 --- a/core/kservices/src/unittest_task.rs +++ b/core/kservices/src/unittest_task.rs @@ -47,7 +47,7 @@ impl InstalledTestThread { let pid = alloc_test_process_id(); let mut aspace = memspace::AddrSpace::new_user_empty()?; - kcore::mm::map_trampoline(&mut aspace)?; + ksignal::map_signal_trampoline(&mut aspace)?; let aspace = Arc::new(Mutex::new(aspace)); let proc = kprocess::Process::new_init(pid); diff --git a/core/kservices/src/vfs/tmp.rs b/core/kservices/src/vfs/tmp.rs deleted file mode 100644 index e4406d9aa..000000000 --- a/core/kservices/src/vfs/tmp.rs +++ /dev/null @@ -1,477 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2025 KylinSoft Co., Ltd. -// See LICENSES for license details. - -use alloc::{borrow::ToOwned, string::String, sync::Arc}; -use core::{any::Any, borrow::Borrow, cmp::Ordering, task::Context, time::Duration}; - -use hashbrown::HashMap; -use kcore::vfs::dummy_stat_fs_with_flags; -use kpoll::{IoEvents, Pollable}; -use ksync::Mutex; -use kvfs::{ - DeviceId, DirEntry, DirEntrySink, DirNode, DirNodeOps, FileNode, FileNodeOps, Filesystem, - FilesystemOps, Metadata, MetadataUpdate, NodeFlags, NodeOps, NodePermission, NodeType, - Reference, StatFs, VfsError, VfsResult, WeakDirEntry, -}; -use slab::Slab; - -#[derive(PartialEq, Eq, Hash, Clone)] -struct FileName(String); - -impl PartialOrd for FileName { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for FileName { - fn cmp(&self, other: &Self) -> Ordering { - fn index(s: &str) -> u8 { - match s { - "." => 0, - ".." => 1, - _ => 2, - } - } - (index(&self.0), &self.0).cmp(&(index(&other.0), &other.0)) - } -} - -impl From for FileName -where - T: Into, -{ - fn from(name: T) -> Self { - Self(name.into()) - } -} - -impl Borrow for FileName { - fn borrow(&self) -> &str { - &self.0 - } -} - -/// A simple in-memory filesystem that supports basic file operations. -pub struct MemoryFs { - mount_flags: u32, - inodes: Mutex>>, - root: Mutex>, -} - -impl MemoryFs { - /// Creates a new empty memory filesystem. - /// Create a new empty in-memory filesystem (tmpfs) - #[allow(clippy::new_ret_no_self)] - pub fn new() -> Filesystem { - Self::new_with_flags(0) - } - - /// Create a new tmpfs instance with explicit statfs mount flags. - #[allow(clippy::new_ret_no_self)] - pub fn new_with_flags(mount_flags: u32) -> Filesystem { - let fs = Arc::new(Self { - mount_flags, - inodes: Mutex::new(Slab::new()), - root: Mutex::default(), - }); - let root_ino = Inode::new( - &fs, - None, - NodeType::Directory, - NodePermission::from_bits_truncate(0o755), - ); - *fs.root.lock() = Some(DirEntry::new_dir( - |this| DirNode::new(MemoryNode::new(fs.clone(), root_ino, Some(this))), - Reference::root(), - )); - Filesystem::new(fs) - } - - fn get(&self, ino: u64) -> Arc { - self.inodes.lock()[ino as usize - 1].clone() - } -} - -impl FilesystemOps for MemoryFs { - fn name(&self) -> &str { - "tmpfs" - } - - fn root_dir(&self) -> DirEntry { - self.root.lock().clone().unwrap() - } - - fn stat(&self) -> VfsResult { - Ok(dummy_stat_fs_with_flags(0x01021994, self.mount_flags)) - } -} - -fn release_inode(fs: &MemoryFs, inode: &Arc, nlink: u64) { - let mut inodes = fs.inodes.lock(); - let mut metadata = inode.metadata.lock(); - metadata.nlink -= nlink; - if metadata.nlink == 0 && Arc::strong_count(inode) == 2 { - inodes.remove(metadata.inode as usize - 1); - } -} - -#[derive(Default)] -struct FileContent { - /// The length of the file content. - /// - /// We only need to store the length here because we delegate the actual - /// content management to page cache. - length: Mutex, - symlink: Mutex>, -} - -#[derive(Default)] -struct DirContent { - entries: Mutex>, -} - -enum NodeContent { - File(FileContent), - Dir(DirContent), -} - -struct Inode { - ino: u64, - metadata: Mutex, - content: NodeContent, -} - -impl Inode { - /// Create a new inode with the given type and permissions - pub fn new( - fs: &Arc, - parent: Option, - node_type: NodeType, - permission: NodePermission, - ) -> Arc { - let mut inodes = fs.inodes.lock(); - let entry = inodes.vacant_entry(); - let ino = entry.key() as u64 + 1; - let metadata = Metadata { - device: 0, - inode: ino, - nlink: 0, - mode: permission, - node_type, - uid: 0, - gid: 0, - size: 0, - block_size: 0, - blocks: 0, - rdev: DeviceId::default(), - atime: Duration::default(), - mtime: Duration::default(), - ctime: Duration::default(), - }; - let content = match node_type { - NodeType::Directory => NodeContent::Dir(DirContent::default()), - _ => NodeContent::File(FileContent::default()), - }; - let result = Arc::new(Self { - ino, - metadata: Mutex::new(metadata), - content, - }); - entry.insert(result.clone()); - drop(inodes); - if let NodeContent::Dir(dir) = &result.content { - let mut entries = dir.entries.lock(); - entries.insert(".".into(), InodeRef::new(fs.clone(), ino)); - entries.insert( - "..".into(), - InodeRef::new(fs.clone(), parent.unwrap_or(ino)), - ); - } - result - } - - fn as_file(&self) -> VfsResult<&FileContent> { - match self.content { - NodeContent::File(ref content) => Ok(content), - _ => Err(VfsError::IsADirectory), - } - } - - fn as_dir(&self) -> VfsResult<&DirContent> { - match self.content { - NodeContent::Dir(ref content) => Ok(content), - _ => Err(VfsError::NotADirectory), - } - } -} - -struct InodeRef { - fs: Arc, - ino: u64, -} - -impl InodeRef { - /// Create a reference to an inode, incrementing link count - pub fn new(fs: Arc, ino: u64) -> Self { - fs.get(ino).metadata.lock().nlink += 1; - Self { fs, ino } - } - - fn get(&self) -> Arc { - self.fs.get(self.ino) - } -} - -impl Drop for InodeRef { - fn drop(&mut self) { - release_inode(&self.fs, &self.get(), 1); - } -} - -struct MemoryNode { - fs: Arc, - inode: Arc, - this: Option, -} - -impl MemoryNode { - /// Create a new memory filesystem node - pub fn new(fs: Arc, inode: Arc, this: Option) -> Arc { - Arc::new(Self { fs, inode, this }) - } - - fn new_entry(&self, name: &str, node_type: NodeType, inode: Arc) -> VfsResult { - let fs = self.fs.clone(); - let reference = Reference::new( - self.this.as_ref().and_then(WeakDirEntry::upgrade), - name.to_owned(), - ); - Ok(if node_type == NodeType::Directory { - DirEntry::new_dir( - |this| DirNode::new(MemoryNode::new(fs, inode, Some(this))), - reference, - ) - } else { - DirEntry::new_file( - FileNode::new(MemoryNode::new(fs, inode, None)), - node_type, - reference, - ) - }) - } -} - -impl NodeOps for MemoryNode { - fn inode(&self) -> u64 { - self.inode.ino - } - - fn metadata(&self) -> VfsResult { - let mut metadata = self.inode.metadata.lock().clone(); - match &self.inode.content { - NodeContent::File(content) => { - metadata.size = *content.length.lock(); - } - NodeContent::Dir(dir) => { - metadata.size = dir.entries.lock().len() as u64; - } - } - Ok(metadata) - } - - fn update_metadata(&self, update: MetadataUpdate) -> VfsResult<()> { - let mut metadata = self.inode.metadata.lock(); - if let Some(mode) = update.mode { - metadata.mode = mode; - } - if let Some((uid, gid)) = update.owner { - metadata.uid = uid; - metadata.gid = gid; - } - if let Some(atime) = update.atime { - metadata.atime = atime; - } - if let Some(mtime) = update.mtime { - metadata.mtime = mtime; - } - Ok(()) - } - - fn filesystem(&self) -> &dyn FilesystemOps { - self.fs.as_ref() - } - - fn sync(&self, _data_only: bool) -> VfsResult<()> { - Ok(()) - } - - fn into_any(self: Arc) -> Arc { - self - } - - fn flags(&self) -> NodeFlags { - NodeFlags::ALWAYS_CACHE - } -} - -impl FileNodeOps for MemoryNode { - fn read_at(&self, buf: &mut [u8], offset: u64) -> VfsResult { - let file = self.inode.as_file()?; - if let Some(symlink) = file.symlink.lock().as_ref() { - assert_eq!(offset, 0); - let len = buf.len().min(symlink.len()); - buf[..len].copy_from_slice(&symlink.as_bytes()[..len]); - return Ok(len); - } - unreachable!("page cache should dispatch_irq reading"); - } - - fn write_at(&self, _buf: &[u8], _offset: u64) -> VfsResult { - unreachable!("page cache should dispatch_irq writing"); - } - - fn append(&self, _buf: &[u8]) -> VfsResult<(usize, u64)> { - unreachable!("page cache should dispatch_irq writing"); - } - - fn set_len(&self, len: u64) -> VfsResult<()> { - *self.inode.as_file()?.length.lock() = len; - Ok(()) - } - - fn set_symlink(&self, target: &str) -> VfsResult<()> { - let file = self.inode.as_file()?; - *file.length.lock() = target.len() as u64; - *file.symlink.lock() = Some(target.to_owned()); - Ok(()) - } -} -impl Pollable for MemoryNode { - fn poll(&self) -> IoEvents { - IoEvents::IN | IoEvents::OUT - } - - fn register(&self, _context: &mut Context<'_>, _events: IoEvents) {} -} - -impl DirNodeOps for MemoryNode { - fn read_dir(&self, offset: u64, sink: &mut dyn DirEntrySink) -> VfsResult { - let mut count = 0; - for (i, (name, entry)) in self - .inode - .as_dir()? - .entries - .lock() - .iter() - .enumerate() - .skip(offset as usize) - { - if !sink.accept( - &name.0, - entry.ino, - entry.get().metadata.lock().node_type, - i as u64 + 1, - ) { - return Ok(count); - } - count += 1; - } - Ok(count) - } - - fn lookup(&self, name: &str) -> VfsResult { - let dir = self.inode.as_dir()?; - let entries = dir.entries.lock(); - - let entry = entries.get(name).ok_or(VfsError::NotFound)?; - let inode = entry.get(); - let node_type = inode.metadata.lock().node_type; - self.new_entry(name, node_type, inode) - } - - fn create( - &self, - name: &str, - node_type: NodeType, - permission: NodePermission, - ) -> VfsResult { - let dir = self.inode.as_dir()?; - let mut entries = dir.entries.lock(); - - if entries.contains_key(name) { - return Err(VfsError::AlreadyExists); - } - let inode = Inode::new(&self.fs, Some(self.inode.ino), node_type, permission); - entries.insert(name.into(), InodeRef::new(self.fs.clone(), inode.ino)); - self.new_entry(name, node_type, inode) - } - - fn link(&self, name: &str, target: &DirEntry) -> VfsResult { - let dir = self.inode.as_dir()?; - let mut entries = dir.entries.lock(); - - let target = target.downcast::()?; - - if entries.contains_key(name) { - return Err(VfsError::AlreadyExists); - } - let inode = target.inode.clone(); - let node_type = target.metadata()?.node_type; - entries.insert(name.into(), InodeRef::new(self.fs.clone(), inode.ino)); - self.new_entry(name, node_type, inode) - } - - fn unlink(&self, name: &str) -> VfsResult<()> { - let dir = self.inode.as_dir()?; - let mut entries = dir.entries.lock(); - - let Some(entry) = entries.get(name) else { - return Err(VfsError::NotFound); - }; - if let NodeContent::Dir(DirContent { entries }) = &entry.get().content - && entries.lock().len() > 2 - { - return Err(VfsError::DirectoryNotEmpty); - } - entries.remove(name); - - Ok(()) - } - - // TODO: atomicity - fn rename(&self, src_name: &str, dst_dir: &DirNode, dst_name: &str) -> VfsResult<()> { - let dst_node = dst_dir.downcast::()?; - if let Ok(entry) = dst_dir.lookup(dst_name) { - let src_entry = self.lookup(src_name)?; - if entry.inode() == src_entry.inode() { - return Ok(()); - } - } - - let src_entry = self - .inode - .as_dir()? - .entries - .lock() - .remove(src_name) - .ok_or(VfsError::NotFound)?; - dst_node - .inode - .as_dir()? - .entries - .lock() - .insert(dst_name.into(), src_entry); - Ok(()) - } -} - -impl Drop for MemoryNode { - fn drop(&mut self) { - if let NodeContent::Dir(dir) = &self.inode.content { - dir.entries.lock().clear(); - } - release_inode(&self.fs, &self.inode, 0); - } -} diff --git a/core/ksyscall/Cargo.toml b/core/ksyscall/Cargo.toml index 4c8d41106..a96268167 100644 --- a/core/ksyscall/Cargo.toml +++ b/core/ksyscall/Cargo.toml @@ -39,7 +39,7 @@ osvm.workspace = true linux_sysno.workspace = true tee_kernel = { workspace = true, optional = true } tee_task_iface = { workspace = true, optional = true } -kcore.workspace = true +kexec.workspace = true posix-credentials.workspace = true posix-fs.workspace = true posix-io-mpx.workspace = true diff --git a/core/ksyscall/src/task/execve.rs b/core/ksyscall/src/task/execve.rs index f73c7470c..fb8a5f0dd 100644 --- a/core/ksyscall/src/task/execve.rs +++ b/core/ksyscall/src/task/execve.rs @@ -13,8 +13,8 @@ use alloc::{string::ToString, sync::Arc, vec::Vec}; use core::ffi::c_char; use kaddr_layout::USER_HEAP_BASE; -use kcore::mm::load_user_app; use kerrno::{KError, KResult}; +use kexec::load_user_app; use khal::uspace::UserContext; use kservices::mm::vm_load_string; use ktask::current; diff --git a/core/kuaccess/Cargo.toml b/core/kuaccess/Cargo.toml new file mode 100644 index 000000000..d48c13490 --- /dev/null +++ b/core/kuaccess/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "kuaccess" +description = "Kernel user-memory access glue for X-Kernel" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +extern-trait = "0.3" +kaddr_layout.workspace = true +khal.workspace = true +kspin.workspace = true +kthread.workspace = true +ktask.workspace = true +linkme.workspace = true +memaddr.workspace = true +osvm.workspace = true +unittest.workspace = true diff --git a/core/kuaccess/src/lib.rs b/core/kuaccess/src/lib.rs new file mode 100644 index 000000000..abf22a41a --- /dev/null +++ b/core/kuaccess/src/lib.rs @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Kernel-side user memory access glue for `osvm`. + +#![no_std] +#![feature(likely_unlikely)] +#![allow(missing_docs)] + +use core::{hint::unlikely, mem::MaybeUninit}; + +use extern_trait::extern_trait; +use kaddr_layout::{USER_SPACE_BASE, USER_SPACE_SIZE}; +use khal::{ + asm::user_copy, + paging::MappingFlags, + trap::{PAGE_FAULT, register_trap_handler}, +}; +use kspin::IrqSave; +use ktask::{current, current_may_uninit}; +use kthread::AsThread; +use memaddr::VirtAddr; +use osvm::{MemError, MemResult, VirtMemIo}; + +/// Enables scoped access into user memory, allowing page faults to occur inside +/// kernel. +pub fn access_user_memory(f: impl FnOnce() -> R) -> R { + let curr = current(); + let Some(thread) = curr.try_as_thread() else { + panic!("access_user_memory called outside of thread context"); + }; + + thread.set_accessing_user_memory(true); + let result = f(); + thread.set_accessing_user_memory(false); + result +} + +#[register_trap_handler(PAGE_FAULT)] +fn dispatch_irq_page_fault(vaddr: VirtAddr, access_flags: MappingFlags) -> bool { + let Some(curr) = current_may_uninit() else { + return false; + }; + let Some(thread) = curr.try_as_thread() else { + return false; + }; + + if unlikely(!thread.is_accessing_user_memory()) { + return false; + } + + thread + .process_state() + .address_space() + .lock() + .dispatch_irq_page_fault(vaddr, access_flags) +} + +#[allow(dead_code)] +struct Vm(IrqSave); + +/// Briefly checks if the given memory region is valid user memory. +pub fn check_access(start: usize, len: usize) -> MemResult { + const USER_SPACE_END: usize = USER_SPACE_BASE + USER_SPACE_SIZE; + let is_accessible = + (USER_SPACE_BASE..USER_SPACE_END).contains(&start) && (USER_SPACE_END - start) >= len; + if unlikely(!is_accessible) { + Err(MemError::NoAccess) + } else { + Ok(()) + } +} + +#[extern_trait] +unsafe impl VirtMemIo for Vm { + fn new() -> Self { + Self(IrqSave::new()) + } + + fn read_mem(&mut self, start: usize, buf: &mut [MaybeUninit]) -> MemResult { + check_access(start, buf.len())?; + let failed_at = access_user_memory(|| unsafe { + user_copy(buf.as_mut_ptr() as *mut _, start as _, buf.len()) + }); + if unlikely(failed_at != 0) { + Err(MemError::NoAccess) + } else { + Ok(()) + } + } + + fn write_mem(&mut self, start: usize, buf: &[u8]) -> MemResult { + check_access(start, buf.len())?; + let failed_at = access_user_memory(|| unsafe { + user_copy(start as _, buf.as_ptr() as *const _, buf.len()) + }); + if unlikely(failed_at != 0) { + Err(MemError::NoAccess) + } else { + Ok(()) + } + } +} + +#[cfg(unittest)] +mod tests { + use osvm::MemError; + use unittest::def_test; + + use super::{USER_SPACE_BASE, USER_SPACE_SIZE, check_access}; + + #[def_test] + fn test_check_access_valid() { + assert!(check_access(USER_SPACE_BASE, 1).is_ok()); + } + + #[def_test] + fn test_check_access_invalid_low() { + let res = check_access(USER_SPACE_BASE - 1, 1); + assert!(matches!(res, Err(MemError::NoAccess))); + } + + #[def_test] + fn test_check_access_invalid_len() { + let res = check_access(USER_SPACE_BASE, USER_SPACE_SIZE + 1); + assert!(matches!(res, Err(MemError::NoAccess))); + } + + #[def_test] + fn test_check_access_zero_len_and_upper_boundary() { + assert!(check_access(USER_SPACE_BASE, 0).is_ok()); + assert!(check_access(USER_SPACE_BASE + USER_SPACE_SIZE - 1, 1).is_ok()); + assert!(check_access(USER_SPACE_BASE + USER_SPACE_SIZE, 0).is_err()); + } + + #[def_test] + fn test_check_access_end_overflow_rejected() { + let res = check_access(USER_SPACE_BASE + USER_SPACE_SIZE - 1, 2); + assert!(matches!(res, Err(MemError::NoAccess))); + } + + #[def_test] + fn test_check_access_rejects_far_above_user_space() { + let res = check_access(USER_SPACE_BASE + USER_SPACE_SIZE + 0x1000, 1); + assert!(matches!(res, Err(MemError::NoAccess))); + } +} diff --git a/entry/Cargo.toml b/entry/Cargo.toml index 5a9471165..71e70e820 100644 --- a/entry/Cargo.toml +++ b/entry/Cargo.toml @@ -26,10 +26,11 @@ cfg-if.workspace = true linkme.workspace = true kprocess.workspace = true kthread.workspace = true +kuaccess.workspace = true ksyscall.workspace = true kservices.workspace = true ktty.workspace = true -kcore.workspace = true +kexec.workspace = true memspace.workspace = true kbuild_config.workspace = true indoc = "2" diff --git a/entry/src/entry.rs b/entry/src/entry.rs index bc1fc9117..c3cdd3525 100644 --- a/entry/src/entry.rs +++ b/entry/src/entry.rs @@ -8,8 +8,8 @@ use alloc::{ sync::Arc, }; -use kcore::mm::load_user_app; use kcred::Credentials; +use kexec::load_user_app; use kfs::{kernel_fs_context, new_process_fs_context}; use khal::uspace::UserContext; use kprocess::{Pid, Process}; diff --git a/entry/src/main.rs b/entry/src/main.rs index f77f0e407..e76ba34d6 100644 --- a/entry/src/main.rs +++ b/entry/src/main.rs @@ -12,6 +12,7 @@ extern crate klogger; extern crate alloc; extern crate kfeat; extern crate kruntime; +extern crate kuaccess; #[cfg(feature = "unittest")] mod unittest_simple; diff --git a/fs/filesystems/devfs/Cargo.toml b/fs/filesystems/devfs/Cargo.toml index dc796cb35..64582fd82 100644 --- a/fs/filesystems/devfs/Cargo.toml +++ b/fs/filesystems/devfs/Cargo.toml @@ -17,7 +17,7 @@ dice = ["dep:dice_driver", "dep:klazy", "dep:rand_chacha", "dep:mbedtls"] [dependencies] kalloc.workspace = true -kcore.workspace = true +kexec.workspace = true kerrno.workspace = true kfs.workspace = true kdriver.workspace = true diff --git a/fs/filesystems/devfs/src/nodes/memtrack.rs b/fs/filesystems/devfs/src/nodes/memtrack.rs index 6be2d45ba..e187a870c 100644 --- a/fs/filesystems/devfs/src/nodes/memtrack.rs +++ b/fs/filesystems/devfs/src/nodes/memtrack.rs @@ -11,7 +11,7 @@ use core::{ }; use backtrace::Backtrace; -use kcore::mm::clear_elf_cache; +use kexec::clear_elf_cache; use kthread::{cleanup_task_tables, tasks}; use kvfs::{DeviceFileOps, NodeFlags, VfsResult}; use kvfs_simple::{DirMapping, SimpleFs}; @@ -49,10 +49,10 @@ impl MemoryCategory { continue; }; match name.as_ref() { - "kcore::mm::ElfLoader::load" => { + "kexec::loader::ElfLoader::load" => { return Some("elf cache"); } - "kcore::task::ProcessState::new" => { + "kthread::process_state::ProcessState::new" => { return Some("process state"); } "kprocess::process::Process::new" => { diff --git a/core/kcore/Cargo.toml b/process/kexec/Cargo.toml similarity index 63% rename from core/kcore/Cargo.toml rename to process/kexec/Cargo.toml index 0444de0fb..4b62a6f35 100644 --- a/core/kcore/Cargo.toml +++ b/process/kexec/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "kcore" -description = "Core kernel crate for X-Kernel" +name = "kexec" +description = "User program loading and exec image setup for X-Kernel" version.workspace = true edition.workspace = true authors.workspace = true @@ -8,39 +8,25 @@ license.workspace = true homepage.workspace = true repository.workspace = true +[features] +tee = ["dep:tee_task_iface", "kthread/tee"] +tee_ta_sign = ["tee_task_iface/tee_ta_sign"] + [dependencies] -backtrace.workspace = true kaddr_layout.workspace = true kerrno.workspace = true -kvfs.workspace = true kfs.workspace = true khal.workspace = true +kernel-elf-parser = { workspace = true } klogger.workspace = true -memspace.workspace = true -memspace_file.workspace = true +ksignal.workspace = true ksync.workspace = true -ktask.workspace = true -bitflags.workspace = true -cfg-if.workspace = true -event-listener.workspace = true -extern-trait.workspace = true -inherit-methods-macro = "0.1.0" -kernel-elf-parser = { workspace = true } -kspin.workspace = true -lazy_static = { workspace = true } -linkme.workspace = true +kthread.workspace = true +kvfs.workspace = true memaddr.workspace = true +memspace.workspace = true +memspace_file.workspace = true ouroboros = { version = "0.18.5", default-features = false } -percpu = { workspace = true } -ksignal.workspace = true -kthread.workspace = true -osvm.workspace = true -strum = { workspace = true } -xmas-elf = "0.9" -unittest.workspace = true -kbuild_config = { workspace = true } tee_task_iface = { workspace = true, optional = true } - -[features] -tee = ["dep:tee_task_iface", "kthread/tee"] -tee_ta_sign = ["tee_task_iface/tee_ta_sign"] +unittest.workspace = true +xmas-elf = "0.9" diff --git a/core/kcore/src/lib.rs b/process/kexec/src/lib.rs similarity index 64% rename from core/kcore/src/lib.rs rename to process/kexec/src/lib.rs index b9de0215e..4d44ca775 100644 --- a/core/kcore/src/lib.rs +++ b/process/kexec/src/lib.rs @@ -2,11 +2,9 @@ // Copyright 2025 KylinSoft Co., Ltd. // See LICENSES for license details. -//! The core functionality of a monolithic kernel, including loading user -//! programs and managing processes. +//! User program loading and exec image setup. #![no_std] -#![feature(likely_unlikely)] #![warn(missing_docs)] #![allow(rustdoc::broken_intra_doc_links, rustdoc::bare_urls)] @@ -15,5 +13,7 @@ extern crate alloc; #[macro_use] extern crate klogger; -mod lrucache; -pub mod mm; +mod loader; +mod lru_cache; + +pub use self::loader::{clear_elf_cache, load_user_app}; diff --git a/core/kcore/src/mm.rs b/process/kexec/src/loader.rs similarity index 65% rename from core/kcore/src/mm.rs rename to process/kexec/src/loader.rs index 18b550576..568b1dbc0 100644 --- a/core/kcore/src/mm.rs +++ b/process/kexec/src/loader.rs @@ -2,46 +2,23 @@ // Copyright 2025 KylinSoft Co., Ltd. // See LICENSES for license details. -//! User address space management. +//! ELF loading for user programs. use alloc::{borrow::ToOwned, string::String, vec, vec::Vec}; -use core::{ffi::CStr, hint::unlikely, iter, mem::MaybeUninit}; +use core::{ffi::CStr, iter}; -use extern_trait::extern_trait; -use kaddr_layout::{USER_SPACE_BASE, USER_SPACE_SIZE}; use kernel_elf_parser::{AuxEntry, ELFHeaders, ELFHeadersBuilder, ELFParser, app_stack_region}; use kerrno::{KError, KResult}; use kfs::{CachedFile, FileBackend}; -use khal::{ - asm::user_copy, - mem::v2p, - paging::{MappingFlags, PageSize}, - trap::{PAGE_FAULT, register_trap_handler}, -}; -use kspin::IrqSave; +use khal::paging::{MappingFlags, PageSize}; use ksync::Mutex; -use ktask::{current, current_may_uninit}; -use kthread::AsThread; use kvfs::Location; use memaddr::{MemoryAddr, PAGE_SIZE_4K, VirtAddr}; use memspace::AddrSpace; use memspace_file::{new_alloc, new_cow}; -use osvm::{MemError, MemResult, VirtMemIo}; use ouroboros::self_referencing; -use crate::lrucache::LruCache; - -/// Map the signal trampoline to the user address space. -pub fn map_trampoline(aspace: &mut AddrSpace) -> KResult { - let signal_trampoline_paddr = v2p(ksignal::arch::signal_trampoline_address().into()); - aspace.map_linear( - kaddr_layout::SIGNAL_TRAMPOLINE.into(), - signal_trampoline_paddr, - PAGE_SIZE_4K, - MappingFlags::READ | MappingFlags::EXECUTE | MappingFlags::USER, - )?; - Ok(()) -} +use super::lru_cache::LruCache; fn mapping_flags(flags: xmas_elf::program::Flags) -> MappingFlags { let mut mapping_flags = MappingFlags::USER; @@ -57,14 +34,6 @@ fn mapping_flags(flags: xmas_elf::program::Flags) -> MappingFlags { mapping_flags } -/// Map the elf file to the user address space. -/// -/// # Arguments -/// - `uspace`: The address space of the user app. -/// - `elf`: The elf file. -/// -/// # Returns -/// - The entry point of the user app. fn map_elf<'a>( uspace: &mut AddrSpace, base: usize, @@ -93,8 +62,8 @@ fn map_elf<'a>( (ph.mem_size as usize + seg_pad + PAGE_SIZE_4K - 1) & !(PAGE_SIZE_4K - 1); let seg_start = VirtAddr::from_usize(vaddr); - // Note that `offset` might not be aligned to 4K here, and it's - // backend's responsibility to properly dispatch_irq it. + // Note that `offset` might not be aligned to 4K here, and it is the + // backend's responsibility to handle it. let backend = new_cow( seg_start, PageSize::Size4K, @@ -147,15 +116,15 @@ impl ElfCacheEntry { } .map_err(map_elf_error) }) { - Ok(e) => { + Ok(entry) => { #[cfg(feature = "tee_ta_sign")] { tee_task_iface::tasign::verify_ta_elf_on_load_and_cache_ta_head( - e.borrow_cache(), + entry.borrow_cache(), ) .map_err(|_err| KError::PermissionDenied)?; } - Ok(Ok(e)) + Ok(Ok(entry)) } Err((_, heads)) => Ok(Err(heads.data)), } @@ -174,10 +143,13 @@ impl ElfLoader { fn load(&mut self, uspace: &mut AddrSpace, path: &str) -> KResult { let loc = kthread::current_fs_context().lock().resolve(path)?; - if !self.0.access(|e| e.borrow_cache().location().ptr_eq(&loc)) { + if !self + .0 + .access(|entry| entry.borrow_cache().location().ptr_eq(&loc)) + { match ElfCacheEntry::load(loc)? { - Ok(e) => { - self.0.put(e); + Ok(entry) => { + self.0.put(entry); } Err(data) => { return Ok(Err(data)); @@ -186,7 +158,7 @@ impl ElfLoader { } uspace.clear(); - map_trampoline(uspace)?; + ksignal::map_signal_trampoline(uspace)?; let entry = self.0.peek_mru().unwrap(); let ldso = if let Some(header) = entry @@ -212,9 +184,12 @@ impl ElfLoader { let (elf, ldso) = if let Some(ldso) = ldso { let loc = kthread::current_fs_context().lock().resolve(ldso)?; - if !self.0.access(|e| e.borrow_cache().location().ptr_eq(&loc)) { - let e = ElfCacheEntry::load(loc)?.map_err(|_| KError::InvalidInput)?; - self.0.put(e); + if !self + .0 + .access(|entry| entry.borrow_cache().location().ptr_eq(&loc)) + { + let entry = ElfCacheEntry::load(loc)?.map_err(|_| KError::InvalidInput)?; + self.0.put(entry); } let mut iter = self.0.items(); @@ -246,7 +221,7 @@ static ELF_LOADER: Mutex = Mutex::new(ElfLoader::new()); /// Clear the ELF cache. /// -/// Useful for removing noises during memory leak detect. +/// Useful for removing noise during memory leak detection. pub fn clear_elf_cache() { ELF_LOADER.lock().0.flush(); #[cfg(feature = "tee_ta_sign")] @@ -256,12 +231,14 @@ pub fn clear_elf_cache() { /// Load the user app to the user address space. /// /// # Arguments +/// /// - `uspace`: The address space of the user app. /// - `args`: The arguments of the user app. The first argument is the path of /// the user app. /// - `envs`: The environment variables of the user app. /// /// # Returns +/// /// - The entry point of the user app. /// - The stack pointer of the user app. pub fn load_user_app( @@ -274,7 +251,7 @@ pub fn load_user_app( .or_else(|| args.first().map(String::as_str)) .ok_or(KError::InvalidInput)?; - // FIXME: impl `/proc/self/exe` to let busybox retry running + // FIXME: Implement `/proc/self/exe` to let busybox retry running scripts. if path.ends_with(".sh") { let new_args: Vec = iter::once("/bin/sh".to_owned()) .chain(args.iter().cloned()) @@ -287,7 +264,10 @@ pub fn load_user_app( Err(data) => { if data.starts_with(b"#!") { let head = &data[2..data.len().min(256)]; - let pos = head.iter().position(|c| *c == b'\n').unwrap_or(head.len()); + let pos = head + .iter() + .position(|byte| *byte == b'\n') + .unwrap_or(head.len()); let line = core::str::from_utf8(&head[..pos]).map_err(|_| KError::InvalidInput)?; let new_args: Vec = line @@ -339,124 +319,13 @@ pub fn load_user_app( Ok((entry, user_sp)) } -/// Enables scoped access into user memory, allowing page faults to occur inside -/// kernel. -pub fn access_user_memory(f: impl FnOnce() -> R) -> R { - let curr = current(); - let Some(thr) = curr.try_as_thread() else { - panic!("access_user_memory called outside of thread context"); - }; - - thr.set_accessing_user_memory(true); - let result = f(); - thr.set_accessing_user_memory(false); - result -} - -#[register_trap_handler(PAGE_FAULT)] -fn dispatch_irq_page_fault(vaddr: VirtAddr, access_flags: MappingFlags) -> bool { - let Some(curr) = current_may_uninit() else { - return false; - }; - let Some(thread) = curr.try_as_thread() else { - return false; - }; - - if unlikely(!thread.is_accessing_user_memory()) { - return false; - } - - thread - .process_state() - .address_space() - .lock() - .dispatch_irq_page_fault(vaddr, access_flags) -} - -#[allow(dead_code)] -struct Vm(IrqSave); - -/// Briefly checks if the given memory region is valid user memory. -pub fn check_access(start: usize, len: usize) -> MemResult { - const USER_SPACE_END: usize = USER_SPACE_BASE + USER_SPACE_SIZE; - let ok = (USER_SPACE_BASE..USER_SPACE_END).contains(&start) && (USER_SPACE_END - start) >= len; - if unlikely(!ok) { - Err(MemError::NoAccess) - } else { - Ok(()) - } -} - -#[extern_trait] -unsafe impl VirtMemIo for Vm { - fn new() -> Self { - Self(IrqSave::new()) - } - - fn read_mem(&mut self, start: usize, buf: &mut [MaybeUninit]) -> MemResult { - check_access(start, buf.len())?; - let failed_at = access_user_memory(|| unsafe { - user_copy(buf.as_mut_ptr() as *mut _, start as _, buf.len()) - }); - if unlikely(failed_at != 0) { - Err(MemError::NoAccess) - } else { - Ok(()) - } - } - - fn write_mem(&mut self, start: usize, buf: &[u8]) -> MemResult { - check_access(start, buf.len())?; - let failed_at = access_user_memory(|| unsafe { - user_copy(start as _, buf.as_ptr() as *const _, buf.len()) - }); - if unlikely(failed_at != 0) { - Err(MemError::NoAccess) - } else { - Ok(()) - } - } -} - -/// Unit tests. #[cfg(unittest)] -pub mod tests_mm { +mod tests { use khal::paging::MappingFlags; - use osvm::MemError; use unittest::def_test; use xmas_elf::program::{FLAG_R, FLAG_W, FLAG_X, Flags}; - use super::{USER_SPACE_BASE, USER_SPACE_SIZE, check_access, mapping_flags}; - - #[def_test] - fn test_check_access_valid() { - assert!(check_access(USER_SPACE_BASE, 1).is_ok()); - } - - #[def_test] - fn test_check_access_invalid_low() { - let res = check_access(USER_SPACE_BASE - 1, 1); - assert!(matches!(res, Err(MemError::NoAccess))); - } - - #[def_test] - fn test_check_access_invalid_len() { - let res = check_access(USER_SPACE_BASE, USER_SPACE_SIZE + 1); - assert!(matches!(res, Err(MemError::NoAccess))); - } - - #[def_test] - fn test_check_access_zero_len_and_upper_boundary() { - assert!(check_access(USER_SPACE_BASE, 0).is_ok()); - assert!(check_access(USER_SPACE_BASE + USER_SPACE_SIZE - 1, 1).is_ok()); - assert!(check_access(USER_SPACE_BASE + USER_SPACE_SIZE, 0).is_err()); - } - - #[def_test] - fn test_check_access_end_overflow_rejected() { - let res = check_access(USER_SPACE_BASE + USER_SPACE_SIZE - 1, 2); - assert!(matches!(res, Err(MemError::NoAccess))); - } + use super::mapping_flags; #[def_test] fn test_mapping_flags_sets_user_and_requested_permissions() { @@ -473,12 +342,6 @@ pub mod tests_mm { assert!(!write_exec.contains(MappingFlags::READ)); } - #[def_test] - fn test_check_access_rejects_far_above_user_space() { - let res = check_access(USER_SPACE_BASE + USER_SPACE_SIZE + 0x1000, 1); - assert!(matches!(res, Err(MemError::NoAccess))); - } - #[def_test] fn test_mapping_flags_all_bits_combination() { let flags = mapping_flags(Flags(FLAG_R | FLAG_W | FLAG_X)); diff --git a/core/kcore/src/lrucache.rs b/process/kexec/src/lru_cache.rs similarity index 86% rename from core/kcore/src/lrucache.rs rename to process/kexec/src/lru_cache.rs index 42cc3d9b8..c1a36aedf 100644 --- a/core/kcore/src/lrucache.rs +++ b/process/kexec/src/lru_cache.rs @@ -9,10 +9,10 @@ use core::mem::replace; /// A simple LRU Cache implementation based on a fixed-size array. /// -/// It maintains a fixed-capacity storage and uses a doubly-linked list -/// indices to track the usage order (from MRU to LRU). +/// It maintains a fixed-capacity storage and uses doubly-linked list indices +/// to track the usage order from MRU to LRU. #[derive(Debug, Clone)] -pub struct LruCache { +pub(super) struct LruCache { storage: Vec>, mru_idx: u16, lru_idx: u16, @@ -34,7 +34,7 @@ impl Default for LruCache { impl LruCache { /// Creates a new empty LRU cache. - pub const fn new() -> Self { + pub(super) const fn new() -> Self { Self { storage: Vec::new(), mru_idx: 0, @@ -44,9 +44,10 @@ impl LruCache { /// Inserts a value into the cache. /// - /// The inserted value becomes the most-recently-used (MRU) item. - /// If the cache is full, the least-recently-used (LRU) item is removed and returned. - pub fn put(&mut self, val: V) -> Option { + /// The inserted value becomes the most-recently-used item. + /// If the cache is full, the least-recently-used item is removed and + /// returned. + pub(super) fn put(&mut self, val: V) -> Option { let node = CacheNode { payload: val, prev: 0, @@ -68,9 +69,10 @@ impl LruCache { /// Accesses an item in the cache that matches the predicate. /// - /// If an item is found, it is promoted to the most-recently-used (MRU) position, - /// and the function returns `true`. Otherwise, it returns `false`. - pub fn access(&mut self, mut pred: F) -> bool + /// If an item is found, it is promoted to the most-recently-used position, + /// and the function returns `true`. + /// Otherwise, it returns `false`. + pub(super) fn access(&mut self, mut pred: F) -> bool where F: FnMut(&V) -> bool, { @@ -83,15 +85,15 @@ impl LruCache { false } - /// Returns a reference to the most-recently-used (MRU) item. + /// Returns a reference to the most-recently-used item. /// /// This does not change the cache state. - pub fn peek_mru(&self) -> Option<&V> { + pub(super) fn peek_mru(&self) -> Option<&V> { self.storage.get(self.mru_idx as usize).map(|n| &n.payload) } /// Returns an iterator over the cache items, ordered from MRU to LRU. - pub fn items(&self) -> LruIter<'_, V, CAP> { + pub(super) fn items(&self) -> LruIter<'_, V, CAP> { LruIter:: { cache: self, pos: self.mru_idx, @@ -99,7 +101,7 @@ impl LruCache { } /// Clears all items from the cache. - pub fn flush(&mut self) { + pub(super) fn flush(&mut self) { self.storage.clear(); } @@ -146,7 +148,7 @@ impl LruCache { } /// Iterator over the `LruCache` items, from MRU to LRU. -pub struct LruIter<'a, V, const CAP: usize> { +pub(super) struct LruIter<'a, V, const CAP: usize> { cache: &'a LruCache, pos: u16, } @@ -175,9 +177,8 @@ impl<'a, V, const CAP: usize> Iterator for LruIter<'a, V, CAP> { } } -/// Unit tests. #[cfg(unittest)] -pub mod tests_lrucache { +mod tests { use unittest::def_test; use super::LruCache; diff --git a/process/ksignal/Cargo.toml b/process/ksignal/Cargo.toml index dc3a16857..8f7c1ee49 100644 --- a/process/ksignal/Cargo.toml +++ b/process/ksignal/Cargo.toml @@ -9,8 +9,10 @@ license.workspace = true repository.workspace = true [dependencies] +kaddr_layout.workspace = true kcpu.workspace = true kerrno.workspace = true +khal.workspace = true bitflags = { workspace = true } cfg-if = { workspace = true } derive_more = { version = "2.0", default-features = false, features = ["full"] } @@ -21,6 +23,8 @@ linux-raw-sys = { workspace = true, default-features = false, features = [ "no_std", ] } log = { workspace = true } +memaddr.workspace = true +memspace.workspace = true osvm = {workspace = true} posix-types.workspace = true strum = { workspace = true } diff --git a/process/ksignal/src/lib.rs b/process/ksignal/src/lib.rs index 0c3bc9a3f..9c7d441b7 100644 --- a/process/ksignal/src/lib.rs +++ b/process/ksignal/src/lib.rs @@ -23,3 +23,6 @@ pub use pending::*; mod types; pub use types::*; + +mod trampoline; +pub use trampoline::map_signal_trampoline; diff --git a/process/ksignal/src/trampoline.rs b/process/ksignal/src/trampoline.rs new file mode 100644 index 000000000..d59ac4a7e --- /dev/null +++ b/process/ksignal/src/trampoline.rs @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Signal trampoline mappings for user address spaces. + +use kerrno::KResult; +use khal::{mem::v2p, paging::MappingFlags}; +use memaddr::PAGE_SIZE_4K; +use memspace::AddrSpace; + +/// Map the signal trampoline to the user address space. +pub fn map_signal_trampoline(aspace: &mut AddrSpace) -> KResult { + let signal_trampoline_paddr = v2p(crate::arch::signal_trampoline_address().into()); + aspace.map_linear( + kaddr_layout::SIGNAL_TRAMPOLINE.into(), + signal_trampoline_paddr, + PAGE_SIZE_4K, + MappingFlags::READ | MappingFlags::EXECUTE | MappingFlags::USER, + )?; + Ok(()) +} -- Gitee From e7dfedcb99b2f3b9a0ee5e374276bfddb1265f2a Mon Sep 17 00:00:00 2001 From: Weikang Guo Date: Fri, 29 May 2026 16:18:48 +0800 Subject: [PATCH 7/8] fix clippy Signed-off-by: Weikang Guo --- mm/memspace/src/aspace.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memspace/src/aspace.rs b/mm/memspace/src/aspace.rs index be44aee35..335a937df 100644 --- a/mm/memspace/src/aspace.rs +++ b/mm/memspace/src/aspace.rs @@ -115,7 +115,7 @@ impl AddrSpace { fn copy_kernel_mappings(&mut self) -> KResult { #[cfg(not(any(target_arch = "aarch64", target_arch = "loongarch64")))] { - self.copy_mappings_from(&memspace::kernel_layout().lock())?; + self.copy_mappings_from(&crate::kernel_layout().lock())?; } Ok(()) } -- Gitee From 6969aab5edd3dad6a9703d9ca13d7761d0100527 Mon Sep 17 00:00:00 2001 From: Weikang Guo Date: Mon, 1 Jun 2026 09:34:09 +0800 Subject: [PATCH 8/8] fix ai review Signed-off-by: Weikang Guo --- Cargo.toml | 2 ++ boot/kernel_elf_parser/Cargo.toml | 2 +- core/kservices/src/unittest_task.rs | 2 ++ core/kuaccess/src/lib.rs | 6 ++++-- process/kexec/Cargo.toml | 4 ++-- tee/tee_task_iface/Cargo.toml | 2 +- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4a8a078a1..f961d4384 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -198,6 +198,7 @@ mbedtls-build-helper = "0.1" mbedtls-platform-support-smx = { version = "0.1", package = "mbedtls-platform-support-smx", default-features = false } mbedtls-sys-auto = { version = "2.28", package = "mbedtls-sys-auto-smx", default-features = false, features = [ ] } +ouroboros = { version = "0.18.5", default-features = false } percpu = "0.4" rust-dice = { version = "0.1", default-features = false } slab = { version = "0.4.9", default-features = false } @@ -213,3 +214,4 @@ buddy-slab-allocator = "0.4" downcast-rs = { version = "2.0", default-features = false, features = ["sync"] } flatten_objects = "0.2.4" weak-map = "0.1.1" +xmas-elf = { version = "0.9", default-features = false } diff --git a/boot/kernel_elf_parser/Cargo.toml b/boot/kernel_elf_parser/Cargo.toml index c6a2630d6..1d9bd0b88 100644 --- a/boot/kernel_elf_parser/Cargo.toml +++ b/boot/kernel_elf_parser/Cargo.toml @@ -12,6 +12,6 @@ keywords = ["ELF", "kernel"] categories = ["no-std"] [dependencies] -xmas-elf = "0.9" +xmas-elf.workspace = true zero = "0.1.3" zerocopy = { version = "0.8.26", features = ["derive"] } diff --git a/core/kservices/src/unittest_task.rs b/core/kservices/src/unittest_task.rs index de294b50b..a92ec9055 100644 --- a/core/kservices/src/unittest_task.rs +++ b/core/kservices/src/unittest_task.rs @@ -46,6 +46,8 @@ impl InstalledTestThread { let tid = current_task.id().as_u64() as Pid; let pid = alloc_test_process_id(); + // `new_user_empty` installs the standard user range and any required + // kernel mappings for the target architecture. let mut aspace = memspace::AddrSpace::new_user_empty()?; ksignal::map_signal_trampoline(&mut aspace)?; let aspace = Arc::new(Mutex::new(aspace)); diff --git a/core/kuaccess/src/lib.rs b/core/kuaccess/src/lib.rs index abf22a41a..58fff6b6a 100644 --- a/core/kuaccess/src/lib.rs +++ b/core/kuaccess/src/lib.rs @@ -6,7 +6,7 @@ #![no_std] #![feature(likely_unlikely)] -#![allow(missing_docs)] +#![warn(missing_docs)] use core::{hint::unlikely, mem::MaybeUninit}; @@ -57,7 +57,9 @@ fn dispatch_irq_page_fault(vaddr: VirtAddr, access_flags: MappingFlags) -> bool .dispatch_irq_page_fault(vaddr, access_flags) } -#[allow(dead_code)] +// `Vm` mirrors the osvm `VirtMemIo` entry point and is kept for future +// direct VM access paths that instantiate the trait-backed adapter. +#[expect(dead_code)] struct Vm(IrqSave); /// Briefly checks if the given memory region is valid user memory. diff --git a/process/kexec/Cargo.toml b/process/kexec/Cargo.toml index 4b62a6f35..05ecf729b 100644 --- a/process/kexec/Cargo.toml +++ b/process/kexec/Cargo.toml @@ -26,7 +26,7 @@ kvfs.workspace = true memaddr.workspace = true memspace.workspace = true memspace_file.workspace = true -ouroboros = { version = "0.18.5", default-features = false } +ouroboros.workspace = true tee_task_iface = { workspace = true, optional = true } unittest.workspace = true -xmas-elf = "0.9" +xmas-elf.workspace = true diff --git a/tee/tee_task_iface/Cargo.toml b/tee/tee_task_iface/Cargo.toml index e44a7c5af..25cd2546a 100644 --- a/tee/tee_task_iface/Cargo.toml +++ b/tee/tee_task_iface/Cargo.toml @@ -31,7 +31,7 @@ uuid = { version = "0.8", default-features = false } unittest.workspace = true kerrno.workspace = true kfs.workspace = true -xmas-elf = { version = "0.9", default-features = false } +xmas-elf = { workspace = true, default-features = false } log.workspace = true ksync = { workspace = true, optional = true } klazy = { workspace = true, optional = true } -- Gitee