From 4c47903fa51390782044b45edc410ebffa0b2503 Mon Sep 17 00:00:00 2001 From: Atheria Date: Sat, 1 Nov 2025 17:53:19 +0700 Subject: [PATCH 1/2] CMake changes --- CMakeLists.txt | 25 ++++---- cmake/ccache.cmake | 34 +++++++++++ cmake/configuration.cmake | 30 ++++++++++ cmake/features.cmake | 121 +++++++++++++++++++++++++++----------- cmake/flags.cmake | 7 ++- voidframe.ld | 2 +- 6 files changed, 172 insertions(+), 47 deletions(-) create mode 100644 cmake/ccache.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 6acb0b3..8e2a004 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,9 @@ enable_language(ASM_NASM) # Module Path & Includes # ============================================================================ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + include(cache) +include(ccache) include(features) include(variable) include(dependencies) @@ -38,7 +40,17 @@ else() endif() if(NOT CMAKE_TOOLCHAIN_FILE) - message(FATAL_ERROR "CMAKE_TOOLCHAIN_FILE is not set. Please provide a toolchain file.") + message(WARNING "CMAKE_TOOLCHAIN_FILE is not set. Automatically selecting toolchain file...") + if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") + set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/cmake/toolchains/linux-x64.cmake" CACHE PATH "Toolchain file" FORCE) + message(STATUS "Defaulting to Linux x86_64 toolchain file: ${CMAKE_TOOLCHAIN_FILE}") + elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/cmake/toolchains/macos-x64.cmake" CACHE PATH "Toolchain file" FORCE) + message(STATUS "Defaulting to macOS x86_64 toolchain file: ${CMAKE_TOOLCHAIN_FILE}") + elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/cmake/toolchains/windows-x64.cmake" CACHE PATH "Toolchain file" FORCE) + message(STATUS "Defaulting to macOS x86_64 toolchain file: ${CMAKE_TOOLCHAIN_FILE}") + endif() else() message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}") endif() @@ -48,12 +60,6 @@ if(NOT CMAKE_BUILD_TYPE) message(WARNING "CMAKE_BUILD_TYPE not set. Defaulting to Release.") endif() -if(CMAKE_GENERATOR STREQUAL "Ninja") - message(STATUS "CMake: Generator: ${CMAKE_GENERATOR}") -else() - message(WARNING "CMake: Non-Ninja generator detected: ${CMAKE_GENERATOR}. Ninja is recommended.") -endif() - if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64") message(STATUS "CMake: Target Architecture: ${CMAKE_SYSTEM_PROCESSOR}") set(Rust_CARGO_TARGET "x86_64-unknown-none") @@ -61,6 +67,7 @@ else() message(FATAL_ERROR "Unsupported target architecture: ${CMAKE_SYSTEM_PROCESSOR}") endif() +message(STATUS "CMake: Generator: ${CMAKE_GENERATOR}") message(STATUS "CMake Build Type: ${CMAKE_BUILD_TYPE}") message(STATUS "CMake Source Directory: ${CMAKE_SOURCE_DIR}") message(STATUS "CMake Binary Directory: ${CMAKE_BINARY_DIR}") @@ -106,10 +113,6 @@ if (SILENT_BUILD) corrosion_add_target_rustflags(voidframe_spinlock "-A" "warnings" "-C" "link-arg=-s") endif() -# ============================================================================ -# Flags setup -# ============================================================================ - # ============================================================================ # Kernel Linking # ============================================================================ diff --git a/cmake/ccache.cmake b/cmake/ccache.cmake new file mode 100644 index 0000000..92d0fd7 --- /dev/null +++ b/cmake/ccache.cmake @@ -0,0 +1,34 @@ +# ============================================================================ +# CCache Configuration for Faster Builds +# ============================================================================ + +option(VF_ENABLE_CCACHE "Enable ccache for faster compilation" ON) + +if(VF_ENABLE_CCACHE) + find_program(CCACHE_PROGRAM ccache) + if(CCACHE_PROGRAM) + # Configure ccache + set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) + set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) + + # Set ccache options for kernel development + set(ENV{CCACHE_SLOPPINESS} "file_macro,locale,time_macros") + set(ENV{CCACHE_MAXSIZE} "2G") + set(ENV{CCACHE_COMPRESS} "true") + set(ENV{CCACHE_COMPRESSLEVEL} "6") + + message(STATUS "ccache enabled: ${CCACHE_PROGRAM}") + + # Show ccache stats + execute_process( + COMMAND ${CCACHE_PROGRAM} -s + OUTPUT_VARIABLE CCACHE_STATS + ERROR_QUIET + ) + if(CCACHE_STATS) + message(STATUS "ccache statistics:\n${CCACHE_STATS}") + endif() + else() + message(WARNING "ccache requested but not found") + endif() +endif() \ No newline at end of file diff --git a/cmake/configuration.cmake b/cmake/configuration.cmake index 332d394..b8b211e 100644 --- a/cmake/configuration.cmake +++ b/cmake/configuration.cmake @@ -6,3 +6,33 @@ option(AUTOMATIC_POST "Run POST automatically on boot" OFF) option(DEBUG_SYMBOLS "Enable debug symbols" ON) option(STACK_PROTECTION "Enable stack protection" ON) option(SILENT_BUILD "Enable silent build (suppress warnings)" OFF) + +option(VF_CONFIG_ENABLE_VMWARE_SVGA_II "Enable VMware SVGA II support" OFF) +option(VF_CONFIG_ENABLE_CERBERUS_VFS_LOGGING "Enable Cerberus VFS logging" OFF) +option(VF_CONFIG_CERBERUS_THREAT_REPORTING "Enable Cerberus threat reporting" OFF) +option(VF_CONFIG_PANIC_OVERRIDE "Enable panic override" OFF) +option(VF_CONFIG_LOAD_MB_MODULES "Enable multiboot module loading" OFF) + +option(VF_CONFIG_ENABLE_XHCI "Enable XHCI support" ON) +option(VF_CONFIG_ENABLE_VIRTIO "Enable VirtIO support" ON) +option(VF_CONFIG_ENABLE_ISA "Enable ISA support" ON) +option(VF_CONFIG_ENABLE_LPT "Enable LPT support" ON) +option(VF_CONFIG_ENABLE_PCI "Enable PCI support" ON) +option(VF_CONFIG_ENABLE_PS2 "Enable PS/2 support" ON) +option(VF_CONFIG_ENABLE_IDE "Enable IDE support" ON) +option(VF_CONFIG_ENABLE_VFCOMPOSITOR "Enable VFCompositor support" ON) +option(VF_CONFIG_ENABLE_AHCI "Enable AHCI support" ON) +option(VF_CONFIG_ENABLE_NVME "Enable NVMe support" ON) +option(VF_CONFIG_ENABLE_GENERIC_SOUND "Enable Generic Sound support" ON) +option(VF_CONFIG_RTC_CENTURY "Enable RTC Century support" ON) +option(VF_CONFIG_ENFORCE_MEMORY_PROTECTION "Enforce memory protection" ON) +option(VF_CONFIG_VM_HOST "Enable VM host optimizations" ON) +option(VF_CONFIG_SNOOZE_ON_BOOT "Enable snooze on boot" ON) +option(VF_CONFIG_USE_VFSHELL "Use VFShell as the default shell" ON) +option(VF_CONFIG_USE_DYNAMOX "Use Dynamox" ON) +option(VF_CONFIG_USE_ASTRA "Use Astra" ON) +option(VF_CONFIG_USE_CERBERUS "Use Cerberus" ON) +option(VF_CONFIG_CERBERUS_STACK_PROTECTION "Enable Cerberus stack protection" ON) +option(VF_CONFIG_INTEL "Enable Intel-specific optimizations" ON) +option(VF_CONFIG_ENABLE_OPIC "Enable OPIC support" ON) +option(VF_CONFIG_VESA_FB "Enable VESA framebuffer support" ON) \ No newline at end of file diff --git a/cmake/features.cmake b/cmake/features.cmake index f0a5f92..c19b07b 100644 --- a/cmake/features.cmake +++ b/cmake/features.cmake @@ -1,40 +1,93 @@ # ============================================================================ # VoidFrame Feature Configuration Flags # ============================================================================ -add_compile_definitions( - VF_CONFIG_ENABLE_XHCI - VF_CONFIG_ENABLE_VIRTIO - VF_CONFIG_ENABLE_ISA - VF_CONFIG_ENABLE_LPT - VF_CONFIG_ENABLE_PCI - VF_CONFIG_ENABLE_PS2 - VF_CONFIG_ENABLE_IDE - VF_CONFIG_ENABLE_VFCOMPOSITOR - VF_CONFIG_ENABLE_AHCI - VF_CONFIG_ENABLE_NVME - VF_CONFIG_ENABLE_GENERIC_SOUND - VF_CONFIG_RTC_CENTURY - VF_CONFIG_ENFORCE_MEMORY_PROTECTION - VF_CONFIG_VM_HOST - VF_CONFIG_SNOOZE_ON_BOOT - VF_CONFIG_PROCINFO_CREATE_DEFAULT - VF_CONFIG_USE_VFSHELL - VF_CONFIG_USE_DYNAMOX - VF_CONFIG_USE_ASTRA - VF_CONFIG_USE_CERBERUS - VF_CONFIG_CERBERUS_STACK_PROTECTION - VF_CONFIG_INTEL - VF_CONFIG_ENABLE_OPIC -) - -add_compile_definitions( - # VF_CONFIG_ENABLE_VMWARE_SVGA_II - # VF_CONFIG_ENABLE_CERBERUS_VFS_LOGGING - # VF_CONFIG_CERBERUS_THREAT_REPORTING - # VF_CONFIG_PROCINFO_AUTO_CLEANUP - # VF_CONFIG_PANIC_OVERRIDE - # VF_CONFIG_LOAD_MB_MODULES -) + +if(VF_CONFIG_ENABLE_XHCI) + add_compile_definitions(VF_CONFIG_ENABLE_XHCI) +endif() +if(VF_CONFIG_ENABLE_VIRTIO) + add_compile_definitions(VF_CONFIG_ENABLE_VIRTIO) +endif() +if(VF_CONFIG_ENABLE_ISA) + add_compile_definitions(VF_CONFIG_ENABLE_ISA) +endif() +if(VF_CONFIG_ENABLE_LPT) + add_compile_definitions(VF_CONFIG_ENABLE_LPT) +endif() +if(VF_CONFIG_ENABLE_PCI) + add_compile_definitions(VF_CONFIG_ENABLE_PCI) +endif() +if(VF_CONFIG_ENABLE_PS2) + add_compile_definitions(VF_CONFIG_ENABLE_PS2) +endif() +if(VF_CONFIG_ENABLE_IDE) + add_compile_definitions(VF_CONFIG_ENABLE_IDE) +endif() +if(VF_CONFIG_ENABLE_VFCOMPOSITOR) + add_compile_definitions(VF_CONFIG_ENABLE_VFCOMPOSITOR) +endif() +if(VF_CONFIG_ENABLE_AHCI) + add_compile_definitions(VF_CONFIG_ENABLE_AHCI) +endif() +if(VF_CONFIG_ENABLE_NVME) + add_compile_definitions(VF_CONFIG_ENABLE_NVME) +endif() +if(VF_CONFIG_ENABLE_GENERIC_SOUND) + add_compile_definitions(VF_CONFIG_ENABLE_GENERIC_SOUND) +endif() +if(VF_CONFIG_RTC_CENTURY) + add_compile_definitions(VF_CONFIG_RTC_CENTURY) +endif() +if(VF_CONFIG_ENFORCE_MEMORY_PROTECTION) + add_compile_definitions(VF_CONFIG_ENFORCE_MEMORY_PROTECTION) +endif() +if(VF_CONFIG_VM_HOST) + add_compile_definitions(VF_CONFIG_VM_HOST) +endif() +if(VF_CONFIG_SNOOZE_ON_BOOT) + add_compile_definitions(VF_CONFIG_SNOOZE_ON_BOOT) +endif() +if(VF_CONFIG_USE_VFSHELL) + add_compile_definitions(VF_CONFIG_USE_VFSHELL) +endif() +if(VF_CONFIG_USE_DYNAMOX) + add_compile_definitions(VF_CONFIG_USE_DYNAMOX) +endif() +if(VF_CONFIG_USE_ASTRA) + add_compile_definitions(VF_CONFIG_USE_ASTRA) +endif() +if(VF_CONFIG_USE_CERBERUS) + add_compile_definitions(VF_CONFIG_USE_CERBERUS) +endif() +if(VF_CONFIG_CERBERUS_STACK_PROTECTION) + add_compile_definitions(VF_CONFIG_CERBERUS_STACK_PROTECTION) +endif() +if(VF_CONFIG_INTEL) + add_compile_definitions(VF_CONFIG_INTEL) +endif() +if(VF_CONFIG_ENABLE_OPIC) + add_compile_definitions(VF_CONFIG_ENABLE_OPIC) +endif() + +if(VF_CONFIG_ENABLE_VMWARE_SVGA_II) + add_compile_definitions(VF_CONFIG_ENABLE_VMWARE_SVGA_II) +endif() + +if(VF_CONFIG_ENABLE_CERBERUS_VFS_LOGGING) + add_compile_definitions(VF_CONFIG_ENABLE_CERBERUS_VFS_LOGGING) +endif() + +if(VF_CONFIG_CERBERUS_THREAT_REPORTING) + add_compile_definitions(VF_CONFIG_CERBERUS_THREAT_REPORTING) +endif() + +if(VF_CONFIG_PANIC_OVERRIDE) + add_compile_definitions(VF_CONFIG_PANIC_OVERRIDE) +endif() + +if(VF_CONFIG_LOAD_MB_MODULES) + add_compile_definitions(VF_CONFIG_LOAD_MB_MODULES) +endif() if(EXCLUDE_EXTRA_OBJECTS) add_compile_definitions(VF_CONFIG_EXCLUDE_EXTRA_OBJECTS) diff --git a/cmake/flags.cmake b/cmake/flags.cmake index b22a5d9..1228b25 100644 --- a/cmake/flags.cmake +++ b/cmake/flags.cmake @@ -22,4 +22,9 @@ endif() set(CMAKE_C_FLAGS "${C_FLAGS}") set(CMAKE_CXX_FLAGS "${C_FLAGS} -fno-exceptions -fno-rtti -fno-threadsafe-statics") -set(CMAKE_ASM_NASM_FLAGS "-f elf64 -DVF_CONFIG_VESA_FB") + +set(ASM_NASM_FLAGS "-f elf64") +if(VF_CONFIG_VESA_FB) + string(APPEND ASM_NASM_FLAGS " -DVF_CONFIG_VESA_FB") +endif() +set(CMAKE_ASM_NASM_FLAGS "${ASM_NASM_FLAGS}") \ No newline at end of file diff --git a/voidframe.ld b/voidframe.ld index f9cea86..a511ce7 100644 --- a/voidframe.ld +++ b/voidframe.ld @@ -76,7 +76,7 @@ SECTIONS *(.comment) *(.note*) *(.eh_frame*) - *(.debug*) + *(.dynamic*) } } From 329809686a0e0c5465fbb747ba6c4588a697905e Mon Sep 17 00:00:00 2001 From: Atheria Date: Sat, 1 Nov 2025 19:02:47 +0700 Subject: [PATCH 2/2] CMake changes --- CMakeLists.txt | 6 +- fs/DriveNaming.c | 10 +-- fs/FileSystem.c | 2 +- fs/Iso9660.c | 4 +- fs/MBR.c | 2 +- fs/procfs/ProcFS.c | 2 +- kernel/atomic/rust/src/ffi.rs | 50 ++++++++++++ kernel/atomic/rust/src/mcs.rs | 123 ++++++++++++++++++++++++++--- kernel/atomic/rust/src/spinlock.rs | 100 ++++++++++++++--------- kernel/etc/Console.c | 10 +-- kernel/etc/Format.c | 6 +- kernel/etc/Format.h | 6 +- kernel/etc/Shell.c | 2 +- kernel/sched/EEVDF.c | 10 +-- kernel/sched/MLFQ.c | 12 +-- mm/security/Cerberus.c | 8 +- 16 files changed, 262 insertions(+), 91 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e2a004..3070483 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,7 @@ if(NOT CMAKE_TOOLCHAIN_FILE) message(STATUS "Defaulting to macOS x86_64 toolchain file: ${CMAKE_TOOLCHAIN_FILE}") elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/cmake/toolchains/windows-x64.cmake" CACHE PATH "Toolchain file" FORCE) - message(STATUS "Defaulting to macOS x86_64 toolchain file: ${CMAKE_TOOLCHAIN_FILE}") + message(STATUS "Defaulting to Windows x86_64 toolchain file: ${CMAKE_TOOLCHAIN_FILE}") endif() else() message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}") @@ -61,13 +61,13 @@ if(NOT CMAKE_BUILD_TYPE) endif() if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64") - message(STATUS "CMake: Target Architecture: ${CMAKE_SYSTEM_PROCESSOR}") + message(STATUS "CMake Target Architecture: ${CMAKE_SYSTEM_PROCESSOR}") set(Rust_CARGO_TARGET "x86_64-unknown-none") else() message(FATAL_ERROR "Unsupported target architecture: ${CMAKE_SYSTEM_PROCESSOR}") endif() -message(STATUS "CMake: Generator: ${CMAKE_GENERATOR}") +message(STATUS "CMake Generator: ${CMAKE_GENERATOR}") message(STATUS "CMake Build Type: ${CMAKE_BUILD_TYPE}") message(STATUS "CMake Source Directory: ${CMAKE_SOURCE_DIR}") message(STATUS "CMake Binary Directory: ${CMAKE_BINARY_DIR}") diff --git a/fs/DriveNaming.c b/fs/DriveNaming.c index aa481ca..a66da35 100644 --- a/fs/DriveNaming.c +++ b/fs/DriveNaming.c @@ -13,19 +13,19 @@ void GenerateDriveNameInto(BlockDeviceType type, char* out_name) { else rust_spinlock_lock(dn_lock); switch (type) { case DEVICE_TYPE_IDE: - FormatA(out_name, 16, "hd%c", 'a' + ide_count++); + snprintf(out_name, 16, "hd%c", 'a' + ide_count++); break; case DEVICE_TYPE_AHCI: - FormatA(out_name, 16, "sd%c", 'a' + ahci_count++); + snprintf(out_name, 16, "sd%c", 'a' + ahci_count++); break; case DEVICE_TYPE_NVME: - FormatA(out_name, 16, "nvme%d", nvme_count++); + snprintf(out_name, 16, "nvme%d", nvme_count++); break; case DEVICE_TYPE_VIRTIO: - FormatA(out_name, 16, "vd%c", 'a' + virtio_count++); + snprintf(out_name, 16, "vd%c", 'a' + virtio_count++); break; default: - FormatA(out_name, 16, "unk%d", 0); + snprintf(out_name, 16, "unk%d", 0); break; } rust_spinlock_unlock(dn_lock); diff --git a/fs/FileSystem.c b/fs/FileSystem.c index 4cbd9d7..0d84088 100644 --- a/fs/FileSystem.c +++ b/fs/FileSystem.c @@ -78,7 +78,7 @@ void FileSystemAutoMount() { PrintKernel("\n"); // Simple mount point naming for now char mount_point[64]; - FormatA(mount_point, sizeof(mount_point), "%s/%s", RuntimeMounts, dev->name); + snprintf(mount_point, sizeof(mount_point), "%s/%s", RuntimeMounts, dev->name); PrintKernel("FS: Mounting at "); PrintKernel(mount_point); PrintKernel("\n"); diff --git a/fs/Iso9660.c b/fs/Iso9660.c index 7a10f16..1e1cc5d 100644 --- a/fs/Iso9660.c +++ b/fs/Iso9660.c @@ -491,8 +491,8 @@ int Iso9660Copy(const char* iso_path, const char* vfs_path) { char vfs_filepath[256]; char iso_filepath[256]; - FormatA(vfs_filepath, sizeof(vfs_filepath), "%s/%s", vfs_path, filename); - FormatA(iso_filepath, sizeof(iso_filepath), "%s/%s", iso_path, filename); + snprintf(vfs_filepath, sizeof(vfs_filepath), "%s/%s", vfs_path, filename); + snprintf(iso_filepath, sizeof(iso_filepath), "%s/%s", iso_path, filename); if (entries[i]->file_flags & 2) { // Directory Iso9660Copy(iso_filepath, vfs_filepath); diff --git a/fs/MBR.c b/fs/MBR.c index fe42780..bf1c9f7 100644 --- a/fs/MBR.c +++ b/fs/MBR.c @@ -72,7 +72,7 @@ void ParseMBR(BlockDevice* device) { if (p->type != 0 && p->num_sectors > 0) { char part_name[32]; - FormatA(part_name, sizeof(part_name), "%s-p%d", device->name, i + 1); + snprintf(part_name, sizeof(part_name), "%s-p%d", device->name, i + 1); PrintKernel("MBR: Registering partition "); PrintKernel(part_name); diff --git a/fs/procfs/ProcFS.c b/fs/procfs/ProcFS.c index 46046b2..c261968 100644 --- a/fs/procfs/ProcFS.c +++ b/fs/procfs/ProcFS.c @@ -75,7 +75,7 @@ int ProcfsReadFile(const char* path, void* buffer, uint32_t max_size) { char local_buffer[1024]; if (FastStrCmp(filename, "info") == 0) { - int len = FormatA(local_buffer, sizeof(local_buffer), + int len = snprintf(local_buffer, sizeof(local_buffer), "Name: %s\n" "PID: %u\n" "State: %d\n" diff --git a/kernel/atomic/rust/src/ffi.rs b/kernel/atomic/rust/src/ffi.rs index 3ad2169..a215dff 100644 --- a/kernel/atomic/rust/src/ffi.rs +++ b/kernel/atomic/rust/src/ffi.rs @@ -73,6 +73,47 @@ pub extern "C" fn rust_spinlock_try_lock(lock: *mut SpinLock) -> bool { } } +#[no_mangle] +pub extern "C" fn rust_spinlock_contention_level(lock: *mut SpinLock) -> u32 { + if !lock.is_null() { + unsafe { (*lock).contention_level() } + } else { + 0 + } +} + +#[no_mangle] +pub extern "C" fn rust_spinlock_lock_order(lock: *mut SpinLock) -> u32 { + if !lock.is_null() { + unsafe { (*lock).lock_order() } + } else { + 0 + } +} + +#[no_mangle] +pub extern "C" fn rust_spinlock_owner_cpu(lock: *mut SpinLock) -> u32 { + if !lock.is_null() { + unsafe { (*lock).owner_cpu() } + } else { + u32::MAX + } +} + +#[no_mangle] +pub extern "C" fn rust_spinlock_new_with_order(order: u32) -> *mut SpinLock { + unsafe { + for i in 0..64 { + if !SPINLOCK_USED[i] { + SPINLOCK_USED[i] = true; + SPINLOCK_STORAGE[i] = SpinLock::new_with_order(order); + return &mut SPINLOCK_STORAGE[i] as *mut SpinLock; + } + } + } + core::ptr::null_mut() +} + // Static storage for MCS locks and nodes static mut MCS_LOCK_STORAGE: [McsLock; 32] = [const { McsLock::new() }; 32]; static mut MCS_LOCK_USED: [bool; 32] = [false; 32]; @@ -147,6 +188,15 @@ pub extern "C" fn rust_mcs_unlock(lock: *mut McsLock, node: *mut McsNode) { } } +#[no_mangle] +pub extern "C" fn rust_mcs_try_lock(lock: *mut McsLock, node: *mut McsNode) -> bool { + if !lock.is_null() && !node.is_null() { + unsafe { (*lock).try_lock(&mut *node) } + } else { + false + } +} + // Static storage for RwLocks static mut RWLOCK_STORAGE: [RwLock; 32] = [const { RwLock::new() }; 32]; static mut RWLOCK_USED: [bool; 32] = [false; 32]; diff --git a/kernel/atomic/rust/src/mcs.rs b/kernel/atomic/rust/src/mcs.rs index 9ee365c..5414e63 100644 --- a/kernel/atomic/rust/src/mcs.rs +++ b/kernel/atomic/rust/src/mcs.rs @@ -1,7 +1,17 @@ use core::sync::atomic::{AtomicPtr, AtomicBool, Ordering}; +use core::arch::x86_64::_mm_pause; +use core::cell::UnsafeCell; +use core::marker::PhantomData; +use core::ops::{Deref, DerefMut}; use core::ptr; -#[repr(C)] +#[inline(always)] +fn pause() { + unsafe { _mm_pause() } +} + +// MCS queue node - each thread has its own +#[repr(C, align(64))] // Cache line aligned pub struct McsNode { next: AtomicPtr, locked: AtomicBool, @@ -16,11 +26,28 @@ impl McsNode { } } +// MCS Lock - fair, NUMA-friendly #[repr(C)] pub struct McsLock { tail: AtomicPtr, } +pub struct McsGuard<'a, T> { + lock: &'a McsLock, + node: &'a mut McsNode, + data: &'a mut T, + _phantom: PhantomData<*const ()>, +} + +#[repr(C)] +pub struct McsMutex { + lock: McsLock, + data: UnsafeCell, +} + +unsafe impl Sync for McsMutex {} +unsafe impl Send for McsMutex {} + impl McsLock { pub const fn new() -> Self { Self { @@ -33,16 +60,20 @@ impl McsLock { node.next.store(ptr::null_mut(), Ordering::Relaxed); node.locked.store(true, Ordering::Relaxed); - let prev = self.tail.swap(node as *mut McsNode, Ordering::AcqRel); + let prev = self.tail.swap(node, Ordering::AcqRel); if !prev.is_null() { + // Queue not empty, link to predecessor unsafe { - (*prev).next.store(node as *mut McsNode, Ordering::Release); + (*prev).next.store(node, Ordering::Release); } + + // Spin on local variable (NUMA-friendly) while node.locked.load(Ordering::Acquire) { - unsafe { core::arch::x86_64::_mm_pause() }; + pause(); } } + // If prev was null, we got the lock immediately } #[inline] @@ -50,20 +81,23 @@ impl McsLock { let next = node.next.load(Ordering::Acquire); if next.is_null() { - if self.tail.compare_exchange( - node as *mut McsNode, - ptr::null_mut(), - Ordering::Release, + // Try to remove ourselves from tail + if self.tail.compare_exchange_weak( + node, + ptr::null_mut(), + Ordering::Release, Ordering::Relaxed ).is_ok() { - return; + return; // Successfully removed, no successor } + // Someone added themselves, wait for next pointer while node.next.load(Ordering::Acquire).is_null() { - unsafe { core::arch::x86_64::_mm_pause() }; + pause(); } } + // Pass lock to next waiter let next = node.next.load(Ordering::Acquire); if !next.is_null() { unsafe { @@ -71,4 +105,73 @@ impl McsLock { } } } + + #[inline] + pub fn try_lock(&self, node: &mut McsNode) -> bool { + node.next.store(ptr::null_mut(), Ordering::Relaxed); + node.locked.store(false, Ordering::Relaxed); + + self.tail.compare_exchange_weak( + ptr::null_mut(), + node, + Ordering::AcqRel, + Ordering::Relaxed + ).is_ok() + } +} + +impl<'a, T> McsGuard<'a, T> { + fn new(lock: &'a McsLock, node: &'a mut McsNode, data: &'a mut T) -> Self { + Self { + lock, + node, + data, + _phantom: PhantomData, + } + } +} + +impl<'a, T> Drop for McsGuard<'a, T> { + fn drop(&mut self) { + self.lock.unlock(self.node); + } +} + +impl<'a, T> Deref for McsGuard<'a, T> { + type Target = T; + fn deref(&self) -> &T { + self.data + } +} + +impl<'a, T> DerefMut for McsGuard<'a, T> { + fn deref_mut(&mut self) -> &mut T { + self.data + } +} + +impl McsMutex { + pub const fn new(data: T) -> Self { + Self { + lock: McsLock::new(), + data: UnsafeCell::new(data), + } + } + + pub fn lock<'a>(&'a self, node: &'a mut McsNode) -> McsGuard<'a, T> { + self.lock.lock(node); + McsGuard::new(&self.lock, node, unsafe { &mut *self.data.get() }) + } + + pub fn try_lock<'a>(&'a self, node: &'a mut McsNode) -> Option> { + if self.lock.try_lock(node) { + Some(McsGuard::new(&self.lock, node, unsafe { &mut *self.data.get() })) + } else { + None + } + } + + pub fn into_inner(self) -> T { + self.data.into_inner() + } } \ No newline at end of file diff --git a/kernel/atomic/rust/src/spinlock.rs b/kernel/atomic/rust/src/spinlock.rs index 0dc0049..46226d8 100644 --- a/kernel/atomic/rust/src/spinlock.rs +++ b/kernel/atomic/rust/src/spinlock.rs @@ -5,9 +5,11 @@ use core::marker::PhantomData; use core::ops::{Deref, DerefMut}; const DEADLOCK_TIMEOUT_CYCLES: u64 = 100_000_000; -const MAX_BACKOFF_CYCLES: u64 = 1024; -const CONTENTION_THRESHOLD: u32 = 16; -const YIELD_THRESHOLD: u32 = 64; +const MAX_BACKOFF_CYCLES: u64 = 512; +const BASE_BACKOFF_CYCLES: u64 = 8; +const CONTENTION_THRESHOLD: u32 = 8; +const YIELD_THRESHOLD: u32 = 32; +const MAX_HOLD_TIME_CYCLES: u64 = 50_000_000; #[inline(always)] fn rdtsc() -> u64 { @@ -20,13 +22,18 @@ fn pause() { } #[inline(always)] -fn backoff_delay(cycles: u64) { - let start = rdtsc(); - while rdtsc() - start < cycles { +fn adaptive_pause(iteration: u32) { + let count = (1 << iteration.min(6)).min(64); + for _ in 0..count { pause(); } } +#[inline(always)] +fn linear_backoff(iteration: u32) -> u64 { + BASE_BACKOFF_CYCLES + (iteration as u64 * BASE_BACKOFF_CYCLES).min(MAX_BACKOFF_CYCLES) +} + extern "C" { fn lapic_get_id() -> u32; } @@ -38,6 +45,7 @@ pub struct SpinLock { contention_count: AtomicU32, owner_cpu: AtomicU32, acquire_time: AtomicU64, + lock_order: AtomicU32, } // RAII guard for automatic unlock @@ -64,19 +72,26 @@ impl SpinLock { contention_count: AtomicU32::new(0), owner_cpu: AtomicU32::new(u32::MAX), acquire_time: AtomicU64::new(0), + lock_order: AtomicU32::new(0), + } + } + + pub const fn new_with_order(order: u32) -> Self { + Self { + locked: AtomicBool::new(false), + contention_count: AtomicU32::new(0), + owner_cpu: AtomicU32::new(u32::MAX), + acquire_time: AtomicU64::new(0), + lock_order: AtomicU32::new(order), } } #[inline] pub fn lock(&self) { let start = rdtsc(); - let mut cpu_id = 0; - unsafe { - cpu_id = lapic_get_id(); - } - let mut backoff = 1u64; + let cpu_id = unsafe { lapic_get_id() }; let mut attempts = 0u32; - let mut local_spins = 0u32; + let mut pause_count = 0u32; loop { // Fast path: try to acquire without contention @@ -84,30 +99,30 @@ impl SpinLock { return; } - // Deadlock detection with owner tracking + // Security: Check for excessive hold time by current owner if rdtsc() - start > DEADLOCK_TIMEOUT_CYCLES { self.handle_potential_deadlock(cpu_id, start); continue; } attempts += 1; - local_spins += 1; - - // Adaptive strategy based on contention level let contention = self.contention_count.load(Ordering::Relaxed); if contention < CONTENTION_THRESHOLD { - // Low contention: aggressive spinning - self.spin_wait_adaptive(local_spins); + // Low contention: CPU-optimized spinning + adaptive_pause(pause_count); + pause_count = (pause_count + 1).min(4); } else if attempts < YIELD_THRESHOLD { - // Medium contention: exponential backoff - backoff_delay(backoff); - backoff = (backoff * 2).min(MAX_BACKOFF_CYCLES); + // Medium contention: linear backoff (better cache behavior) + let delay = linear_backoff(attempts); + let start_delay = rdtsc(); + while rdtsc() - start_delay < delay { + pause(); + } } else { - // High contention: yield to scheduler + // High contention: yield and reset unsafe { crate::ffi::Yield(); } - local_spins = 0; - // Reset attempts to prevent immediate re-yielding if not scheduled away + pause_count = 0; attempts = 0; } } @@ -124,31 +139,28 @@ impl SpinLock { false } - #[inline] - fn spin_wait_adaptive(&self, local_spins: u32) { - let spin_count = if local_spins < 32 { 4 } else { 16 }; - for _ in 0..spin_count { - if !self.locked.load(Ordering::Relaxed) { - break; - } - pause(); - } - } + #[inline] fn handle_potential_deadlock(&self, cpu_id: u32, start_time: u64) { let owner = self.owner_cpu.load(Ordering::Relaxed); let owner_time = self.acquire_time.load(Ordering::Relaxed); - // In a real kernel, this would check if owner CPU is still alive - // and potentially break the lock or log the deadlock + // Security: Detect self-deadlock if owner == cpu_id { - // Self-deadlock detected - this should never happen return; } - // Force yield and reset timing - backoff_delay(MAX_BACKOFF_CYCLES); + // Security: Check if lock held too long + if owner_time > 0 && rdtsc() - owner_time > MAX_HOLD_TIME_CYCLES { + panic!("Lock held too long!"); + } + + // Aggressive backoff for potential deadlock + let delay_start = rdtsc(); + while rdtsc() - delay_start < MAX_BACKOFF_CYCLES { + pause(); + } self.contention_count.fetch_add(1, Ordering::Relaxed); } @@ -189,6 +201,16 @@ impl SpinLock { pub fn contention_level(&self) -> u32 { self.contention_count.load(Ordering::Relaxed) } + + #[inline] + pub fn lock_order(&self) -> u32 { + self.lock_order.load(Ordering::Relaxed) + } + + #[inline] + pub fn owner_cpu(&self) -> u32 { + self.owner_cpu.load(Ordering::Relaxed) + } } // RAII Guard implementation diff --git a/kernel/etc/Console.c b/kernel/etc/Console.c index 4347da6..a64e02a 100644 --- a/kernel/etc/Console.c +++ b/kernel/etc/Console.c @@ -273,7 +273,7 @@ void PrintKernelF(const char* format, ...) { char buffer[1024]; va_list args; va_start(args, format); - Format(buffer, sizeof(buffer), format, args); + vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); PrintKernel(buffer); } @@ -282,7 +282,7 @@ void PrintKernelWarningF(const char* format, ...) { char buffer[1024]; va_list args; va_start(args, format); - Format(buffer, sizeof(buffer), format, args); + vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); PrintKernelWarning(buffer); } @@ -291,7 +291,7 @@ void PrintKernelErrorF(const char* format, ...) { char buffer[1024]; va_list args; va_start(args, format); - Format(buffer, sizeof(buffer), format, args); + vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); PrintKernelError(buffer); } @@ -300,7 +300,7 @@ void PrintKernelSuccessF(const char* format, ...) { char buffer[1024]; va_list args; va_start(args, format); - Format(buffer, sizeof(buffer), format, args); + vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); PrintKernelSuccess(buffer); } @@ -309,7 +309,7 @@ void SerialWriteF(const char* format, ...) { char buffer[1024]; va_list args; va_start(args, format); - Format(buffer, sizeof(buffer), format, args); + vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); SerialWrite(buffer); } diff --git a/kernel/etc/Format.c b/kernel/etc/Format.c index 6105259..d3f4c6c 100644 --- a/kernel/etc/Format.c +++ b/kernel/etc/Format.c @@ -226,11 +226,7 @@ int vsprintf(char *buf, const char *fmt, va_list args) return vsnprintf(buf, 0x7FFFFFFF, fmt, args); } -int Format(char* buffer, size_t size, const char* format, va_list args) { - return vsnprintf(buffer, size, format, args); -} - -int FormatA(char* buffer, size_t size, const char* format, ...) { +int snprintf(char* buffer, size_t size, const char* format, ...) { va_list args; va_start(args, format); int result = vsnprintf(buffer, size, format, args); diff --git a/kernel/etc/Format.h b/kernel/etc/Format.h index 0f0e974..b32d1d6 100644 --- a/kernel/etc/Format.h +++ b/kernel/etc/Format.h @@ -29,12 +29,12 @@ * * @param buffer Pointer to the character array where the formatted string will be stored. * @param size Size of the buffer, including space for the null-terminator. - * @param format Pointer to a null-terminated format string. + * @param fmt Pointer to a null-terminated format string. * @param args Variable argument list containing the data to format. * @return The number of characters written to the buffer, excluding the null-terminator. * Returns -1 if the buffer is null or the size is zero. */ -int Format(char* buffer, size_t size, const char* format, va_list args); +int vsnprintf(char *buffer, size_t size, const char *fmt, va_list args); /** * @alias vsnprintf @@ -45,7 +45,7 @@ int Format(char* buffer, size_t size, const char* format, va_list args); * @param ... Format param(s) * @return */ -int FormatA(char* buffer, size_t size, const char* format, ...); +int snprintf(char* buffer, size_t size, const char* format, ...); /** * @brief An UNSAFE version and deprecated version of Format wrapper diff --git a/kernel/etc/Shell.c b/kernel/etc/Shell.c index 61f8657..07c1b40 100644 --- a/kernel/etc/Shell.c +++ b/kernel/etc/Shell.c @@ -1207,7 +1207,7 @@ static void MountHandler(const char* args) { } char mount_point[64]; - FormatA(mount_point, sizeof(mount_point), "%s/%s", RuntimeMounts, dev_name); + snprintf(mount_point, sizeof(mount_point), "%s/%s", RuntimeMounts, dev_name); if (FastStrCmp(fs_type, "fat1x") == 0) { Fat1xMount(dev, mount_point); diff --git a/kernel/sched/EEVDF.c b/kernel/sched/EEVDF.c index 80bf677..3ef0a74 100644 --- a/kernel/sched/EEVDF.c +++ b/kernel/sched/EEVDF.c @@ -857,7 +857,7 @@ int EEVDFSchedInit(void) { // Initialize idle process EEVDFProcessControlBlock* idle_proc = &processes[0]; - FormatA(idle_proc->name, sizeof(idle_proc->name), "Idle"); + snprintf(idle_proc->name, sizeof(idle_proc->name), "Idle"); idle_proc->pid = 0; idle_proc->state = PROC_RUNNING; idle_proc->privilege_level = EEVDF_PROC_PRIV_SYSTEM; @@ -877,7 +877,7 @@ int EEVDFSchedInit(void) { token->checksum = EEVDFCalculateTokenChecksum(token); token->pcb_hash = EEVDFCalculatePCBHash(idle_proc); - FormatA(idle_proc->ProcessRuntimePath, sizeof(idle_proc->ProcessRuntimePath), "%s/%d", RuntimeServices, idle_proc->pid); + snprintf(idle_proc->ProcessRuntimePath, sizeof(idle_proc->ProcessRuntimePath), "%s/%d", RuntimeServices, idle_proc->pid); ProcFSRegisterProcess(0, 0); @@ -957,7 +957,7 @@ uint32_t EEVDFCreateSecureProcess(const char* name, void (*entry_point)(void), u // Initialize process EEVDFProcessControlBlock* proc = &processes[slot]; - FormatA(proc->name, sizeof(proc->name), "%s", name ? name : FormatS("proc%d", slot)); + snprintf(proc->name, sizeof(proc->name), "%s", name ? name : FormatS("proc%d", slot)); proc->pid = new_pid; proc->state = PROC_READY; proc->stack = stack; @@ -998,7 +998,7 @@ uint32_t EEVDFCreateSecureProcess(const char* name, void (*entry_point)(void), u proc->ipc_queue.tail = 0; proc->ipc_queue.count = 0; - FormatA(proc->ProcessRuntimePath, sizeof(proc->ProcessRuntimePath), "%s/%d", RuntimeProcesses, new_pid); + snprintf(proc->ProcessRuntimePath, sizeof(proc->ProcessRuntimePath), "%s/%d", RuntimeProcesses, new_pid); // Recalculate PCB hash after all relevant fields are set token->pcb_hash = EEVDFCalculatePCBHash(proc); @@ -1010,7 +1010,7 @@ uint32_t EEVDFCreateSecureProcess(const char* name, void (*entry_point)(void), u ProcFSRegisterProcess(new_pid, stack); // Update counters - __sync_fetch_and_add(&process_count, 1); + AtomicInc(&process_count); ready_process_bitmap |= (1ULL << slot); eevdf_scheduler.total_processes++; diff --git a/kernel/sched/MLFQ.c b/kernel/sched/MLFQ.c index 193064d..a93fe3a 100644 --- a/kernel/sched/MLFQ.c +++ b/kernel/sched/MLFQ.c @@ -694,7 +694,7 @@ static void SmartAging(void) { static inline __attribute__((visibility("hidden"))) __attribute__((always_inline)) int RuntimePathValidation(const MLFQProcessControlBlock * proc) { char expected[sizeof(proc->ProcessRuntimePath)]; - FormatA(expected, sizeof(expected), "%s/%d", RuntimeProcesses, proc->pid); + snprintf(expected, sizeof(expected), "%s/%d", RuntimeProcesses, proc->pid); return FastStrCmp(proc->ProcessRuntimePath, expected) == 0; } @@ -1062,7 +1062,7 @@ uint32_t MLFQCreateSecureProcess(const char * name, void (*entry_point)(void), u } // Initialize process with enhanced security and scheduling data - FormatA(processes[slot].name, sizeof(processes[slot].name), "%s", name ? name : FormatS("proc%d", slot)); + snprintf(processes[slot].name, sizeof(processes[slot].name), "%s", name ? name : FormatS("proc%d", slot)); processes[slot].pid = new_pid; processes[slot].state = PROC_READY; processes[slot].stack = stack; @@ -1076,7 +1076,7 @@ uint32_t MLFQCreateSecureProcess(const char * name, void (*entry_point)(void), u processes[slot].io_operations = 0; processes[slot].preemption_count = 0; processes[slot].wait_time = 0; - FormatA(processes[slot].ProcessRuntimePath, sizeof(processes[slot].ProcessRuntimePath), "%s/%d", RuntimeProcesses, new_pid); + snprintf(processes[slot].ProcessRuntimePath, sizeof(processes[slot].ProcessRuntimePath), "%s/%d", RuntimeProcesses, new_pid); #ifdef VF_CONFIG_USE_CERBERUS CerberusRegisterProcess(new_pid, (uint64_t)stack, STACK_SIZE); #endif @@ -1464,7 +1464,7 @@ static void Astra(void) { // register security_manager_pid = current->pid; - FormatA(astra_path, sizeof(astra_path), "%s/astra", current->ProcessRuntimePath); + snprintf(astra_path, sizeof(astra_path), "%s/astra", current->ProcessRuntimePath); if (VfsCreateFile(astra_path) != 0) PANIC("Failed to create Astra process info file"); PrintKernelSuccess("Astra: Astra active.\n"); @@ -1677,13 +1677,13 @@ int MLFQSchedInit(void) { InitSchedulerNodePool(); // Initialize idle process MLFQProcessControlBlock* idle_proc = &processes[0]; - FormatA(idle_proc->name, sizeof(idle_proc->name), "Idle"); + snprintf(idle_proc->name, sizeof(idle_proc->name), "Idle"); idle_proc->pid = 0; idle_proc->state = PROC_RUNNING; idle_proc->privilege_level = PROC_PRIV_SYSTEM; idle_proc->scheduler_node = NULL; idle_proc->creation_time = MLFQGetSystemTicks(); - FormatA(idle_proc->ProcessRuntimePath, sizeof(idle_proc->ProcessRuntimePath), "%s/%d", RuntimeServices, idle_proc->pid); + snprintf(idle_proc->ProcessRuntimePath, sizeof(idle_proc->ProcessRuntimePath), "%s/%d", RuntimeServices, idle_proc->pid); ProcFSRegisterProcess(0, 0); // Securely initialize the token for the Idle Process MLFQSecurityToken* token = &idle_proc->token; diff --git a/mm/security/Cerberus.c b/mm/security/Cerberus.c index 0a80fe6..8c2d023 100644 --- a/mm/security/Cerberus.c +++ b/mm/security/Cerberus.c @@ -32,7 +32,7 @@ void CerberusLogViolation(CerberusViolationReport* report) { #ifdef VF_CONFIG_CERBERUS_VFS_LOGGING // VFS logging char log_entry[256]; - FormatA(log_entry, sizeof(log_entry), + snprintf(log_entry, sizeof(log_entry), "TICK=%lu PID=%d TYPE=%d ADDR=0x%lx RIP=0x%lx DESC=%s\n", system_ticks, report->process_id, report->violation_type, report->fault_address, report->rip, report->description); @@ -196,7 +196,7 @@ int CerberusCheckStackCanary(uint32_t pid) { .rip = 0 }; - FormatA(violation.description, sizeof(violation.description), + snprintf(violation.description, sizeof(violation.description), "Stack canary corrupted: expected=0x%lx found=0x%lx", STACK_CANARY_VALUE, canary_value); @@ -288,7 +288,7 @@ int CerberusAnalyzeFault(uint64_t fault_addr, uint64_t error_code, uint32_t pid, .rip = rip }; - FormatA(violation.description, sizeof(violation.description), + snprintf(violation.description, sizeof(violation.description), "Memory fault: addr=0x%lx error=0x%lx rip=0x%lx", fault_addr, error_code, rip); @@ -380,7 +380,7 @@ int CerberusTrackFree(uint64_t addr, uint32_t pid) { .rip = 0 }; - FormatA(violation.description, sizeof(violation.description), + snprintf(violation.description, sizeof(violation.description), "Potential double-free: addr=0x%lx", addr); CerberusLogViolation(&violation);