diff --git a/Cargo.toml b/Cargo.toml index 24a2ee70bb..3891f8ff3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,14 +54,6 @@ default = [ #! ### Syscall Features -## Enables multiple address spaces. -## -## This feature makes Hermit use traditional system calls for communicating with the kernel -## instead of using function calls. -## -## Note that this feature is not complete yet. -common-os = [] - ## Enables support for memory management system calls. ## ## This feature enables functions similar to [sys/mman.h]. diff --git a/hermit-macro/src/system.rs b/hermit-macro/src/system.rs index 1ee6a8bb95..0f42353ed8 100644 --- a/hermit-macro/src/system.rs +++ b/hermit-macro/src/system.rs @@ -185,7 +185,7 @@ fn emit_func(func: ItemFn, sig: &ParsedSig, errno: bool) -> Result { cfg_select! { all( feature = "kernel-stack", - not(any(target_arch = "riscv64", feature = "common-os")), + not(target_arch = "riscv64"), ) => { unsafe { crate::arch::kernel::kernel_stack::#kernel_function_ident(#(#args,)* #kernel_ident) } } @@ -266,7 +266,7 @@ mod tests { cfg_select! { all( feature = "kernel-stack", - not(any(target_arch = "riscv64", feature = "common-os")), + not(target_arch = "riscv64"), ) => { unsafe { crate::arch::kernel::kernel_stack::kernel_function2(a, b, _sys_test) } } @@ -335,7 +335,7 @@ mod tests { cfg_select! { all( feature = "kernel-stack", - not(any(target_arch = "riscv64", feature = "common-os")), + not(target_arch = "riscv64"), ) => { unsafe { crate::arch::kernel::kernel_stack::kernel_function2(a, b, _sys_test) } } @@ -406,7 +406,7 @@ mod tests { cfg_select! { all( feature = "kernel-stack", - not(any(target_arch = "riscv64", feature = "common-os")), + not(target_arch = "riscv64"), ) => { unsafe { crate::arch::kernel::kernel_stack::kernel_function2(a, b, _sys_test) } } diff --git a/src/arch/aarch64/kernel/scheduler.rs b/src/arch/aarch64/kernel/scheduler.rs index a58cb4baa3..a8aa533431 100644 --- a/src/arch/aarch64/kernel/scheduler.rs +++ b/src/arch/aarch64/kernel/scheduler.rs @@ -280,7 +280,6 @@ extern "C" fn task_start(_f: extern "C" fn(usize), _arg: usize) -> ! { impl TaskFrame for Task { fn create_stack_frame(&mut self, func: unsafe extern "C" fn(usize), arg: usize) { // Check if TLS is allocated already and if the task uses thread-local storage. - #[cfg(not(feature = "common-os"))] if self.tls.is_none() { use crate::scheduler::task::tls::Tls; @@ -297,7 +296,6 @@ impl TaskFrame for Task { stack -= size_of::(); let state = stack.as_mut_ptr::(); - #[cfg(not(feature = "common-os"))] if let Some(tls) = &self.tls { (*state).tpidr_el0 = tls.thread_ptr().expose_provenance() as u64; } diff --git a/src/arch/riscv64/kernel/scheduler.rs b/src/arch/riscv64/kernel/scheduler.rs index a4f5b44cdb..aad419f825 100644 --- a/src/arch/riscv64/kernel/scheduler.rs +++ b/src/arch/riscv64/kernel/scheduler.rs @@ -276,7 +276,6 @@ impl TaskFrame for Task { fn create_stack_frame(&mut self, func: unsafe extern "C" fn(usize), arg: usize) { // Check if the task (process or thread) uses Thread-Local-Storage. // check is TLS is already allocated - #[cfg(not(feature = "common-os"))] if self.tls.is_none() { use crate::scheduler::task::tls::Tls; @@ -293,7 +292,6 @@ impl TaskFrame for Task { stack -= size_of::(); let state = stack.as_mut_ptr::(); - #[cfg(not(feature = "common-os"))] if let Some(tls) = &self.tls { (*state).tp = tls.thread_ptr().expose_provenance(); } diff --git a/src/arch/x86_64/kernel/gdt.rs b/src/arch/x86_64/kernel/gdt.rs index 74ce775980..69d6e86189 100644 --- a/src/arch/x86_64/kernel/gdt.rs +++ b/src/arch/x86_64/kernel/gdt.rs @@ -6,8 +6,6 @@ use core::sync::atomic::Ordering; use x86_64::VirtAddr; use x86_64::instructions::tables; use x86_64::registers::segmentation::{CS, DS, ES, SS, Segment}; -#[cfg(feature = "common-os")] -use x86_64::structures::gdt::DescriptorFlags; use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable}; use x86_64::structures::tss::TaskStateSegment; @@ -22,13 +20,6 @@ pub fn add_current_core() { let gdt: &mut GlobalDescriptorTable = Box::leak(Box::new(GlobalDescriptorTable::new())); let kernel_code_selector = gdt.append(Descriptor::kernel_code_segment()); let kernel_data_selector = gdt.append(Descriptor::kernel_data_segment()); - #[cfg(feature = "common-os")] - { - let _user_code32_selector = - gdt.append(Descriptor::UserSegment(DescriptorFlags::USER_CODE32.bits())); - let _user_data64_selector = gdt.append(Descriptor::user_data_segment()); - let _user_code64_selector = gdt.append(Descriptor::user_code_segment()); - } // Dynamically allocate memory for a Task-State Segment (TSS) for this core. let tss = Box::leak(Box::new(TaskStateSegment::new())); @@ -73,24 +64,5 @@ pub fn add_current_core() { } pub extern "C" fn set_current_kernel_stack() { - #[cfg(feature = "common-os")] - { - use x86_64::PhysAddr; - use x86_64::registers::control::Cr3; - use x86_64::structures::paging::PhysFrame; - - let root = crate::scheduler::get_root_page_table(); - let new_frame = - PhysFrame::from_start_address(PhysAddr::new(root.try_into().unwrap())).unwrap(); - - let (current_frame, val) = Cr3::read_raw(); - - if current_frame != new_frame { - unsafe { - Cr3::write_raw(new_frame, val); - } - } - } - core_scheduler().set_current_kernel_stack(); } diff --git a/src/arch/x86_64/kernel/mod.rs b/src/arch/x86_64/kernel/mod.rs index b413d5bab9..efcedda7e7 100644 --- a/src/arch/x86_64/kernel/mod.rs +++ b/src/arch/x86_64/kernel/mod.rs @@ -1,8 +1,4 @@ -#[cfg(feature = "common-os")] -use core::arch::asm; use core::ptr; -#[cfg(feature = "common-os")] -use core::slice; use core::sync::atomic::{AtomicPtr, AtomicU32, Ordering}; use x86_64::registers::control::{Cr0, Cr4}; @@ -30,8 +26,6 @@ pub mod processor; pub mod scheduler; pub mod serial; pub mod switch; -#[cfg(feature = "common-os")] -mod syscall; pub(crate) mod systemtime; #[cfg(feature = "vga")] pub mod vga; @@ -153,142 +147,3 @@ pub fn print_statistics() { pub static CPU_ONLINE: AtomicU32 = AtomicU32::new(0); pub static CURRENT_STACK_ADDRESS: AtomicPtr = AtomicPtr::new(ptr::null_mut()); - -#[cfg(feature = "common-os")] -const LOADER_START: usize = 0x0100_0000_0000; -#[cfg(feature = "common-os")] -const LOADER_STACK_SIZE: usize = 0x8000; - -#[cfg(feature = "common-os")] -pub fn load_application(code_size: u64, tls_size: u64, func: F) -> T -where - F: FnOnce(&'static mut [u8], Option<&'static mut [u8]>) -> T, -{ - use align_address::Align; - use free_list::PageLayout; - use memory_addresses::{PhysAddr, VirtAddr}; - use x86_64::structures::paging::{PageSize, Size4KiB as BasePageSize}; - - use crate::arch::mm::paging::{self, PageTableEntryFlags, PageTableEntryFlagsExt}; - use crate::mm::{FrameAlloc, PageRangeAllocator}; - - let code_size = (code_size as usize + LOADER_STACK_SIZE).align_up(BasePageSize::SIZE as usize); - let layout = PageLayout::from_size_align(code_size, BasePageSize::SIZE as usize).unwrap(); - let frame_range = FrameAlloc::allocate(layout).unwrap(); - let physaddr = PhysAddr::from(frame_range.start()); - - let mut flags = PageTableEntryFlags::empty(); - flags.normal().writable().user().execute_enable(); - paging::map::( - VirtAddr::from(LOADER_START), - physaddr, - code_size / BasePageSize::SIZE as usize, - flags, - ); - - let loader_start_ptr = ptr::with_exposed_provenance_mut(LOADER_START); - let code_slice = unsafe { slice::from_raw_parts_mut(loader_start_ptr, code_size) }; - - if tls_size > 0 { - // To access TLS blocks on x86-64, TLS offsets are *subtracted* from the thread register value. - // So the thread pointer needs to be `block_ptr + tls_offset`. - // GNU style TLS requires `fs:0` to represent the same address as the thread pointer. - // Since the thread pointer points to the end of the TLS blocks, we need to store it there. - let tcb_size = size_of::<*mut ()>(); - let tls_offset = tls_size as usize; - - let tls_memsz = (tls_offset + tcb_size).align_up(BasePageSize::SIZE as usize); - let layout = PageLayout::from_size(tls_memsz).unwrap(); - let frame_range = FrameAlloc::allocate(layout).unwrap(); - let physaddr = PhysAddr::from(frame_range.start()); - - let mut flags = PageTableEntryFlags::empty(); - flags.normal().writable().user().execute_disable(); - let tls_virt = VirtAddr::from(LOADER_START + code_size + BasePageSize::SIZE as usize); - paging::map::( - tls_virt, - physaddr, - tls_memsz / BasePageSize::SIZE as usize, - flags, - ); - let block = - unsafe { slice::from_raw_parts_mut(tls_virt.as_mut_ptr(), tls_offset + tcb_size) }; - for elem in block.iter_mut() { - *elem = 0; - } - - // thread_ptr = block_ptr + tls_offset - let thread_ptr = block[tls_offset..].as_mut_ptr().cast::<()>(); - unsafe { - thread_ptr.cast::<*mut ()>().write(thread_ptr); - } - processor::writefs(thread_ptr.expose_provenance()); - - func(code_slice, Some(block)) - } else { - func(code_slice, None) - } -} - -#[cfg(feature = "common-os")] -pub unsafe fn jump_to_user_land(entry_point: usize, code_size: usize, arg: &[&str]) -> ! { - use alloc::ffi::CString; - - use align_address::Align; - use x86_64::structures::paging::{PageSize, Size4KiB as BasePageSize}; - - use crate::arch::kernel::scheduler::TaskStacks; - - info!("Create new file descriptor table"); - core_scheduler().recreate_objmap().unwrap(); - - let entry_point: usize = LOADER_START | entry_point; - let stack_pointer: usize = LOADER_START - + (code_size + LOADER_STACK_SIZE).align_up(BasePageSize::SIZE.try_into().unwrap()) - - 8; - - let stack_pointer = stack_pointer - 128 /* red zone */ - arg.len() * size_of::<*mut u8>(); - let stack_ptr = ptr::with_exposed_provenance_mut::<*mut u8>(stack_pointer); - let argv = unsafe { slice::from_raw_parts_mut(stack_ptr, arg.len()) }; - let len = arg.iter().fold(0, |acc, x| acc + x.len() + 1); - // align stack pointer to fulfill the requirements of the x86_64 ABI - let stack_pointer = (stack_pointer - len).align_down(16) - size_of::(); - - let mut pos: usize = 0; - for (i, s) in arg.iter().enumerate() { - let s = CString::new(*s).unwrap(); - let bytes = s.as_bytes_with_nul(); - argv[i] = ptr::with_exposed_provenance_mut::(stack_pointer + pos); - pos += bytes.len(); - - unsafe { - argv[i].copy_from_nonoverlapping(bytes.as_ptr(), bytes.len()); - } - } - - debug!("Jump to user space at 0x{entry_point:x}, stack pointer 0x{stack_pointer:x}"); - - unsafe { - asm!( - "and rsp, {0}", - "swapgs", - "push {1}", - "push {2}", - "push {3}", - "push {4}", - "push {5}", - "mov rdi, {6}", - "mov rsi, {7}", - "iretq", - const u64::MAX - (TaskStacks::MARKER_SIZE as u64 - 1), - const 0x23usize, - in(reg) stack_pointer, - const 0x1202u64, - const 0x2busize, - in(reg) entry_point, - in(reg) argv.len(), - in(reg) argv.as_ptr(), - options(nostack, noreturn) - ); - } -} diff --git a/src/arch/x86_64/kernel/processor.rs b/src/arch/x86_64/kernel/processor.rs index 3d65b6b57d..7419801b16 100644 --- a/src/arch/x86_64/kernel/processor.rs +++ b/src/arch/x86_64/kernel/processor.rs @@ -874,37 +874,6 @@ pub fn configure() { } } - // enable support of syscall and sysret - #[cfg(feature = "common-os")] - { - use x86_64::PrivilegeLevel; - use x86_64::registers::model_specific::{LStar, SFMask, Star}; - use x86_64::registers::rflags::RFlags; - use x86_64::structures::gdt::SegmentSelector; - - use crate::arch::kernel::syscall; - - let has_syscall = match cpuid.get_extended_processor_and_feature_identifiers() { - Some(finfo) => finfo.has_syscall_sysret(), - None => false, - }; - - if has_syscall { - info!("Enable SYSCALL support"); - } else { - panic!("Syscall support is missing"); - } - let cs_sysret = SegmentSelector::new(5, PrivilegeLevel::Ring3); - let ss_sysret = SegmentSelector::new(4, PrivilegeLevel::Ring3); - let cs_syscall = SegmentSelector::new(1, PrivilegeLevel::Ring0); - let ss_syscall = SegmentSelector::new(2, PrivilegeLevel::Ring0); - Star::write(cs_sysret, ss_sysret, cs_syscall, ss_syscall).unwrap(); - let syscall_handler_addr = syscall::syscall_handler as *const (); - let syscall_handler_addr = VirtAddr::from_ptr(syscall_handler_addr); - LStar::write(syscall_handler_addr); - SFMask::write(RFlags::INTERRUPT_FLAG); // clear IF flag during system call - } - // Initialize the FS register, which is later used for Thread-Local Storage. writefs(0); diff --git a/src/arch/x86_64/kernel/scheduler.rs b/src/arch/x86_64/kernel/scheduler.rs index afa12b5650..d8f1a46494 100644 --- a/src/arch/x86_64/kernel/scheduler.rs +++ b/src/arch/x86_64/kernel/scheduler.rs @@ -19,9 +19,6 @@ use crate::scheduler::{PerCoreSchedulerExt, timer_interrupts}; #[repr(C, packed)] struct State { - #[cfg(feature = "common-os")] - /// GS register - gs: u64, /// FS register for TLS support fs: u64, /// R15 register @@ -269,7 +266,6 @@ extern "C" fn task_entry(func: extern "C" fn(usize), arg: usize) -> ! { impl TaskFrame for Task { fn create_stack_frame(&mut self, func: unsafe extern "C" fn(usize), arg: usize) { // Check if TLS is allocated already and if the task uses thread-local storage. - #[cfg(not(feature = "common-os"))] if self.tls.is_none() { use crate::scheduler::task::tls::Tls; @@ -286,7 +282,6 @@ impl TaskFrame for Task { stack -= size_of::(); let state = stack.as_mut_ptr::(); - #[cfg(not(feature = "common-os"))] if let Some(tls) = &self.tls { (*state).fs = tls.thread_ptr().addr() as u64; } diff --git a/src/arch/x86_64/kernel/switch.rs b/src/arch/x86_64/kernel/switch.rs index dc1675f03c..9842706939 100644 --- a/src/arch/x86_64/kernel/switch.rs +++ b/src/arch/x86_64/kernel/switch.rs @@ -4,23 +4,7 @@ use x86_64::registers::control::Cr0Flags; use crate::arch::kernel::gdt::set_current_kernel_stack; -#[cfg(not(feature = "common-os"))] -macro_rules! push_gs { - () => { - r#" - "# - }; -} - -#[cfg(not(feature = "common-os"))] -macro_rules! pop_gs { - () => { - r#" - "# - }; -} - -#[cfg(all(feature = "fsgsbase", feature = "common-os"))] +#[cfg(feature = "fsgsbase")] macro_rules! push_gs { () => { r#" @@ -30,7 +14,7 @@ macro_rules! push_gs { }; } -#[cfg(all(feature = "fsgsbase", feature = "common-os"))] +#[cfg(feature = "fsgsbase")] macro_rules! pop_gs { () => { r#" @@ -40,7 +24,7 @@ macro_rules! pop_gs { }; } -#[cfg(all(not(feature = "fsgsbase"), feature = "common-os"))] +#[cfg(not(feature = "fsgsbase"))] macro_rules! push_gs { () => { r#" @@ -53,7 +37,7 @@ macro_rules! push_gs { }; } -#[cfg(all(not(feature = "fsgsbase"), feature = "common-os"))] +#[cfg(not(feature = "fsgsbase"))] macro_rules! pop_gs { () => { r#" diff --git a/src/arch/x86_64/kernel/syscall.rs b/src/arch/x86_64/kernel/syscall.rs deleted file mode 100644 index cc50cab8be..0000000000 --- a/src/arch/x86_64/kernel/syscall.rs +++ /dev/null @@ -1,49 +0,0 @@ -use core::arch::naked_asm; -use core::mem; - -use super::core_local::CoreLocal; -use crate::syscalls::table::SYSHANDLER_TABLE; - -#[unsafe(no_mangle)] -#[unsafe(naked)] -pub(crate) unsafe extern "C" fn syscall_handler() -> ! { - naked_asm!( - // save context, see x86_64 ABI - "push rcx", - "push rdx", - "push rsi", - "push rdi", - "push r8", - "push r9", - "push r10", - "push r11", - // switch to kernel stack - "swapgs", - "mov rcx, rsp", - "mov rsp, gs:{core_local_kernel_stack}", - // save user stack pointer - "push rcx", - // copy 4th argument to rcx to adhere x86_64 ABI - "mov rcx, r10", - "sti", - "mov r10, qword ptr [rip + {table}@GOTPCREL]", - "call [r10 + 8*rax]", - "cli", - // restore user stack pointer - "pop rcx", - "mov rsp, rcx", - "swapgs", - // restore context, see x86_64 ABI - "pop r11", - "pop r10", - "pop r9", - "pop r8", - "pop rdi", - "pop rsi", - "pop rdx", - "pop rcx", - "sysretq", - core_local_kernel_stack = const mem::offset_of!(CoreLocal, kernel_stack), - table = sym SYSHANDLER_TABLE, - ); -} diff --git a/src/arch/x86_64/mm/mod.rs b/src/arch/x86_64/mm/mod.rs index 43982e292c..e643195406 100644 --- a/src/arch/x86_64/mm/mod.rs +++ b/src/arch/x86_64/mm/mod.rs @@ -1,63 +1,9 @@ pub(crate) mod paging; -#[cfg(feature = "common-os")] -use core::slice; - use memory_addresses::arch::x86_64::{PhysAddr, VirtAddr}; -#[cfg(feature = "common-os")] -use x86_64::structures::paging::{PageSize, Size4KiB as BasePageSize}; -#[cfg(feature = "common-os")] -use crate::arch::mm::paging::{PageTableEntryFlags, PageTableEntryFlagsExt}; use crate::mm::{FrameAlloc, PageAlloc, PageRangeAllocator}; -#[cfg(feature = "common-os")] -pub fn create_new_root_page_table() -> usize { - use free_list::PageLayout; - use x86_64::registers::control::Cr3; - - use crate::mm::PageBox; - - let layout = PageLayout::from_size(BasePageSize::SIZE as usize).unwrap(); - let frame_range = FrameAlloc::allocate(layout).unwrap(); - let physaddr = PhysAddr::from(frame_range.start()); - - let layout = PageLayout::from_size(2 * BasePageSize::SIZE as usize).unwrap(); - let page_range = PageBox::new(layout).unwrap(); - let virtaddr = VirtAddr::from(page_range.start()); - let mut flags = PageTableEntryFlags::empty(); - flags.normal().writable(); - - let entry: u64 = unsafe { - let (frame, _flags) = Cr3::read(); - paging::map::(virtaddr, frame.start_address().into(), 1, flags); - let entry: &u64 = &*virtaddr.as_ptr(); - - *entry - }; - - let slice_addr = virtaddr + BasePageSize::SIZE; - paging::map::(slice_addr, physaddr, 1, flags); - - unsafe { - let pml4 = slice::from_raw_parts_mut(slice_addr.as_mut_ptr(), 512); - - // clear PML4 - for elem in pml4.iter_mut() { - *elem = 0; - } - - // copy first element and the self reference - pml4[0] = entry; - // create self reference - pml4[511] = physaddr.as_u64() + 0x3; // PG_PRESENT | PG_RW - }; - - paging::unmap::(virtaddr, 2); - - physaddr.as_usize() -} - pub unsafe fn init() { paging::init(); unsafe { @@ -69,14 +15,4 @@ pub unsafe fn init() { unsafe { PageAlloc::init(); } - - #[cfg(feature = "common-os")] - { - use x86_64::registers::control::Cr3; - - let (frame, _flags) = Cr3::read(); - crate::scheduler::BOOT_ROOT_PAGE_TABLE - .set(frame.start_address().as_u64().try_into().unwrap()) - .unwrap(); - } } diff --git a/src/arch/x86_64/mm/paging.rs b/src/arch/x86_64/mm/paging.rs index 3f9f3e9f02..f0e2e38641 100644 --- a/src/arch/x86_64/mm/paging.rs +++ b/src/arch/x86_64/mm/paging.rs @@ -2,8 +2,6 @@ use core::{fmt, ptr}; use free_list::PageLayout; use x86_64::registers::control::{Cr0, Cr0Flags, Cr2, Cr3}; -#[cfg(feature = "common-os")] -use x86_64::registers::segmentation::SegmentSelector; pub use x86_64::structures::idt::InterruptStackFrame as ExceptionStackFrame; use x86_64::structures::idt::PageFaultErrorCode; pub use x86_64::structures::paging::PageTableFlags as PageTableEntryFlags; @@ -43,16 +41,6 @@ pub trait PageTableEntryFlagsExt { fn writable(&mut self) -> &mut Self; fn execute_disable(&mut self) -> &mut Self; - - #[cfg(feature = "common-os")] - fn execute_enable(&mut self) -> &mut Self; - - #[cfg(feature = "common-os")] - fn user(&mut self) -> &mut Self; - - #[expect(dead_code)] - #[cfg(feature = "common-os")] - fn kernel(&mut self) -> &mut Self; } impl PageTableEntryFlagsExt for PageTableEntryFlags { @@ -80,24 +68,6 @@ impl PageTableEntryFlagsExt for PageTableEntryFlags { self.insert(PageTableEntryFlags::NO_EXECUTE); self } - - #[cfg(feature = "common-os")] - fn execute_enable(&mut self) -> &mut Self { - self.remove(PageTableEntryFlags::NO_EXECUTE); - self - } - - #[cfg(feature = "common-os")] - fn user(&mut self) -> &mut Self { - self.insert(PageTableEntryFlags::USER_ACCESSIBLE); - self - } - - #[cfg(feature = "common-os")] - fn kernel(&mut self) -> &mut Self { - self.remove(PageTableEntryFlags::USER_ACCESSIBLE); - self - } } pub use x86_64::structures::paging::{ @@ -293,7 +263,6 @@ where } } -#[cfg(not(feature = "common-os"))] pub(crate) extern "x86-interrupt" fn page_fault_handler( stack_frame: ExceptionStackFrame, error_code: PageFaultErrorCode, @@ -307,25 +276,6 @@ pub(crate) extern "x86-interrupt" fn page_fault_handler( scheduler::abort(); } -#[cfg(feature = "common-os")] -pub(crate) extern "x86-interrupt" fn page_fault_handler( - mut stack_frame: ExceptionStackFrame, - error_code: PageFaultErrorCode, -) { - unsafe { - if stack_frame.as_mut().read().code_segment != SegmentSelector(0x08) { - core::arch::asm!("swapgs", options(nostack)); - } - } - error!("Page fault (#PF)!"); - error!("page_fault_linear_address = {:p}", Cr2::read().unwrap()); - error!("error_code = {error_code:?}"); - error!("fs = {:#X}", processor::readfs()); - error!("gs = {:#X}", processor::readgs()); - error!("stack_frame = {stack_frame:#?}"); - scheduler::abort(); -} - pub fn init() { unsafe { log_page_tables(); diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs index a8fd8ca37f..0ac2841b53 100644 --- a/src/arch/x86_64/mod.rs +++ b/src/arch/x86_64/mod.rs @@ -3,23 +3,7 @@ pub mod mm; #[cfg(target_os = "none")] pub mod start; -#[cfg(feature = "common-os")] -use x86_64::registers::segmentation::SegmentSelector; - use crate::arch::mm::paging::ExceptionStackFrame; -/// Swap the GS register, if the user-space is is interrupted. -#[cfg(feature = "common-os")] -#[inline(always)] -pub(crate) fn swapgs(stack_frame: &ExceptionStackFrame) { - use core::arch::asm; - if stack_frame.code_segment != SegmentSelector(8) { - unsafe { - asm!("swapgs", options(nomem, nostack, preserves_flags)); - } - } -} - -#[cfg(not(feature = "common-os"))] #[inline(always)] pub(crate) fn swapgs(_stack_frame: &ExceptionStackFrame) {} diff --git a/src/common_os.rs b/src/common_os.rs deleted file mode 100644 index 46e46274c1..0000000000 --- a/src/common_os.rs +++ /dev/null @@ -1 +0,0 @@ -pub use crate::arch::kernel::{jump_to_user_land, load_application}; diff --git a/src/errno.rs b/src/errno.rs index a06fc74e28..f1aab4f7e9 100644 --- a/src/errno.rs +++ b/src/errno.rs @@ -678,10 +678,7 @@ impl From for Errno { } /// Returns the pointer to `errno`. -#[cfg(all( - not(any(feature = "common-os", feature = "nostd")), - not(target_arch = "riscv64"), -))] +#[cfg(all(not(feature = "nostd"), not(target_arch = "riscv64"),))] #[unsafe(no_mangle)] #[linkage = "weak"] pub extern "C" fn sys_errno_location() -> *mut i32 { @@ -709,7 +706,7 @@ pub extern "C" fn sys_get_errno() -> i32 { #[unsafe(no_mangle)] pub extern "C" fn sys_errno() -> i32 { cfg_select! { - any(feature = "common-os", target_arch = "riscv64") => 0, + target_arch = "riscv64" => 0, _ => unsafe { *sys_errno_location() }, } } @@ -725,7 +722,7 @@ pub(crate) trait ToErrno { { if let Some(errno) = self.to_errno() { cfg_select! { - any(feature = "common-os", feature = "nostd", target_arch = "riscv64") => { + any(feature = "nostd", target_arch = "riscv64") => { let _ = errno; } _ => unsafe { diff --git a/src/lib.rs b/src/lib.rs index 6ab2f3ace9..8fc23a320a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,10 +47,7 @@ #![feature(allocator_api)] #![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr( - all( - not(any(feature = "common-os", feature = "nostd")), - not(target_arch = "riscv64"), - ), + all(not(feature = "nostd"), not(target_arch = "riscv64"),), feature(linkage) )] #![feature(linked_list_cursors)] @@ -60,10 +57,7 @@ feature(specialization) )] #![cfg_attr( - all( - not(any(feature = "common-os", feature = "nostd")), - not(target_arch = "riscv64"), - ), + all(not(feature = "nostd"), not(target_arch = "riscv64"),), feature(thread_local) )] #![cfg_attr(target_os = "none", no_std)] @@ -96,8 +90,6 @@ mod macros; mod logging; pub mod arch; -#[cfg(all(feature = "common-os", target_arch = "x86_64"))] -pub mod common_os; pub mod config; pub mod console; mod drivers; diff --git a/src/mm/mod.rs b/src/mm/mod.rs index bfb73fb7ee..fc3d46d73e 100644 --- a/src/mm/mod.rs +++ b/src/mm/mod.rs @@ -3,7 +3,6 @@ //! This is an overview of Hermit's memory layout: //! //! - `DeviceAlloc.device_offset` is 0 if `!cfg!(careful)` -//! - User space virtual memory is only used if `!cfg!(feature = "common-os")` //! - On x86-64, PCI BARs, I/O APICs, and local APICs may be in `0xc0000000..0xffffffff`, which could be inside of `MEM`. //! //! ```text @@ -35,7 +34,7 @@ //! │ │ ├───┼──► kernel_virt_end //! │ │ │ │ //! Empty │ │ │ │ -//! │ │ │ │ User space +//! │ │ │ │ //! │ │ │ │ //! │ │ │ │ //! ``` @@ -121,100 +120,51 @@ pub(crate) fn init() { let mut map_addr; let mut map_size; - let heap_start_addr; - #[cfg(feature = "common-os")] - { - info!("Using Hermit as common OS!"); - - // we reserve at least 75% of the memory for the user space - let reserve: usize = (avail_mem * 75) / 100; - // 64 MB is enough as kernel heap - let reserve = core::cmp::min(reserve, 0x0400_0000); - - let virt_size: usize = reserve.align_down(LargePageSize::SIZE as usize); - let layout = PageLayout::from_size_align(virt_size, LargePageSize::SIZE as usize).unwrap(); - let page_range = PageAlloc::allocate(layout).unwrap(); - let virt_addr = VirtAddr::from(page_range.start()); - heap_start_addr = virt_addr; - - info!( - "Heap: size {} MB, start address {:p}", - virt_size >> 20, - virt_addr - ); + // we reserve 10% of the memory for stack allocations + #[cfg(not(feature = "mman"))] + let stack_reserve: usize = (avail_mem * 10) / 100; - #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] - if has_1gib_pages && virt_size > HugePageSize::SIZE as usize { - // Mount large pages to the next huge page boundary - let npages = (virt_addr.align_up(HugePageSize::SIZE) - virt_addr) as usize - / LargePageSize::SIZE as usize; - if let Err(n) = paging::map_heap::(virt_addr, npages) { - map_addr = virt_addr + n as u64 * LargePageSize::SIZE; - map_size = virt_size - (map_addr - virt_addr) as usize; - } else { - map_addr = virt_addr.align_up(HugePageSize::SIZE); - map_size = virt_size - (map_addr - virt_addr) as usize; - } - } else { - map_addr = virt_addr; - map_size = virt_size; - } + // At first, we map only a small part into the heap. + // Afterwards, we already use the heap and map the rest into + // the virtual address space. - #[cfg(not(any(target_arch = "x86_64", target_arch = "riscv64")))] - { - map_addr = virt_addr; - map_size = virt_size; - } - } + #[cfg(not(feature = "mman"))] + let virt_size: usize = (avail_mem - stack_reserve).align_down(LargePageSize::SIZE as usize); + #[cfg(feature = "mman")] + let virt_size: usize = ((avail_mem * 75) / 100).align_down(LargePageSize::SIZE as usize); - #[cfg(not(feature = "common-os"))] - { - // we reserve 10% of the memory for stack allocations - #[cfg(not(feature = "mman"))] - let stack_reserve: usize = (avail_mem * 10) / 100; - - // At first, we map only a small part into the heap. - // Afterwards, we already use the heap and map the rest into - // the virtual address space. - - #[cfg(not(feature = "mman"))] - let virt_size: usize = (avail_mem - stack_reserve).align_down(LargePageSize::SIZE as usize); - #[cfg(feature = "mman")] - let virt_size: usize = ((avail_mem * 75) / 100).align_down(LargePageSize::SIZE as usize); - - let layout = PageLayout::from_size_align(virt_size, LargePageSize::SIZE as usize).unwrap(); - let page_range = PageAlloc::allocate(layout).unwrap(); - let virt_addr = VirtAddr::from(page_range.start()); - heap_start_addr = virt_addr; - - info!( - "Heap: size {} MB, start address {:p}", - virt_size >> 20, - virt_addr - ); + let layout = PageLayout::from_size_align(virt_size, LargePageSize::SIZE as usize).unwrap(); + let page_range = PageAlloc::allocate(layout).unwrap(); + let virt_addr = VirtAddr::from(page_range.start()); + let heap_start_addr = virt_addr; + + info!( + "Heap: size {} MB, start address {:p}", + virt_size >> 20, + virt_addr + ); - #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] - if has_1gib_pages && virt_size > HugePageSize::SIZE as usize { - // Mount large pages to the next huge page boundary - let npages = (virt_addr.align_up(HugePageSize::SIZE) - virt_addr) / LargePageSize::SIZE; - if let Err(n) = paging::map_heap::(virt_addr, npages as usize) { - map_addr = virt_addr + n as u64 * LargePageSize::SIZE; - map_size = virt_size - (map_addr - virt_addr) as usize; - } else { - map_addr = virt_addr.align_up(HugePageSize::SIZE); - map_size = virt_size - (map_addr - virt_addr) as usize; - } + #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] + if has_1gib_pages && virt_size > HugePageSize::SIZE as usize { + // Mount large pages to the next huge page boundary + let npages = (virt_addr.align_up(HugePageSize::SIZE) - virt_addr) / LargePageSize::SIZE; + if let Err(n) = paging::map_heap::(virt_addr, npages as usize) { + map_addr = virt_addr + n as u64 * LargePageSize::SIZE; + map_size = virt_size - (map_addr - virt_addr) as usize; } else { - map_addr = virt_addr; - map_size = virt_size; + map_addr = virt_addr.align_up(HugePageSize::SIZE); + map_size = virt_size - (map_addr - virt_addr) as usize; } + } else { + map_addr = virt_addr; + map_size = virt_size; + } - #[cfg(not(any(target_arch = "x86_64", target_arch = "riscv64")))] - { - map_addr = virt_addr; - map_size = virt_size; - } + #[cfg(not(any(target_arch = "x86_64", target_arch = "riscv64")))] + { + map_addr = virt_addr; + map_size = virt_size; } #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] diff --git a/src/mm/virtualmem.rs b/src/mm/virtualmem.rs index 807c6f3a6e..8171d2dcec 100644 --- a/src/mm/virtualmem.rs +++ b/src/mm/virtualmem.rs @@ -77,11 +77,7 @@ pub fn kernel_heap_end() -> VirtAddr { target_arch = "x86_64" => { use x86_64::structures::paging::PageTableIndex; - let p4_index = if cfg!(feature = "common-os") { - PageTableIndex::new(1) - } else { - PageTableIndex::new(256) - }; + let p4_index = PageTableIndex::new(256); let addr = u64::from(p4_index) << 39; assert_eq!(VirtAddr::new_truncate(addr).p4_index(), p4_index); diff --git a/src/rt.rs b/src/rt.rs index 64283bcdd0..ba6ead465b 100644 --- a/src/rt.rs +++ b/src/rt.rs @@ -42,9 +42,9 @@ fn trivial_test() { /// Entry point of a kernel thread, which initialize the libos extern "C" fn initd(_arg: usize) { unsafe extern "C" { - #[cfg(all(not(test), not(any(feature = "nostd", feature = "common-os"))))] + #[cfg(all(not(test), not(feature = "nostd")))] fn runtime_entry(argc: i32, argv: *const *const u8, env: *const *const u8) -> !; - #[cfg(all(not(test), any(feature = "nostd", feature = "common-os")))] + #[cfg(all(not(test), feature = "nostd"))] fn main(argc: i32, argv: *const *const u8, env: *const *const u8); } @@ -75,9 +75,9 @@ extern "C" fn initd(_arg: usize) { #[cfg(not(test))] unsafe { // And finally start the application. - #[cfg(all(not(test), not(any(feature = "nostd", feature = "common-os"))))] + #[cfg(all(not(test), not(feature = "nostd")))] runtime_entry(argc, argv, environ); - #[cfg(all(not(test), any(feature = "nostd", feature = "common-os")))] + #[cfg(all(not(test), feature = "nostd"))] main(argc, argv, environ); } #[cfg(test)] diff --git a/src/scheduler/mod.rs b/src/scheduler/mod.rs index e5d8ae802a..8061cb5d84 100644 --- a/src/scheduler/mod.rs +++ b/src/scheduler/mod.rs @@ -463,33 +463,6 @@ impl PerCoreScheduler { }) } - /// Creates a new map between file descriptor and their IO interface and - /// clone the standard descriptors. - #[cfg(feature = "common-os")] - #[cfg_attr(not(target_arch = "x86_64"), expect(dead_code))] - pub fn recreate_objmap(&self) -> io::Result<()> { - let mut map = HashMap::>, RandomState>::with_hasher( - RandomState::with_seeds(0, 0, 0, 0), - ); - - without_interrupts(|| { - let mut current_task = self.current_task.borrow_mut(); - let object_map = current_task.object_map.read(); - - // clone standard file descriptors - for i in 0..3 { - if let Some(obj) = object_map.get(&i) { - map.insert(i, obj.clone()); - } - } - - drop(object_map); - current_task.object_map = Arc::new(RwSpinLock::new(map)); - }); - - Ok(()) - } - /// Insert a new IO interface and returns a file descriptor as /// identifier to this object pub fn insert_object(&self, obj: Arc>) -> io::Result { @@ -951,12 +924,3 @@ pub fn shutdown(arg: i32) -> ! { fn get_task_handle(id: TaskId) -> Option { TASKS.lock().get(&id).copied() } - -#[cfg(all(target_arch = "x86_64", feature = "common-os"))] -pub(crate) static BOOT_ROOT_PAGE_TABLE: OnceCell = OnceCell::new(); - -#[cfg(all(target_arch = "x86_64", feature = "common-os"))] -pub(crate) fn get_root_page_table() -> usize { - let current_task_borrowed = core_scheduler().current_task.borrow_mut(); - current_task_borrowed.root_page_table -} diff --git a/src/scheduler/task/mod.rs b/src/scheduler/task/mod.rs index e5e1fe171d..d7432e7d92 100644 --- a/src/scheduler/task/mod.rs +++ b/src/scheduler/task/mod.rs @@ -1,6 +1,5 @@ #![allow(clippy::type_complexity)] -#[cfg(not(feature = "common-os"))] pub(crate) mod tls; use alloc::collections::{LinkedList, VecDeque}; @@ -16,7 +15,6 @@ use hashbrown::HashMap; use hermit_sync::{OnceCell, RwSpinLock}; use memory_addresses::VirtAddr; -#[cfg(not(feature = "common-os"))] use self::tls::Tls; use super::timer_interrupts::{Source, create_timer_abs}; use crate::arch::kernel::core_local::*; @@ -381,11 +379,7 @@ pub(crate) struct Task { /// Mapping between file descriptor and the referenced IO interface pub object_map: Arc>, RandomState>>>, /// Task Thread-Local-Storage (TLS) - #[cfg(not(feature = "common-os"))] pub tls: Option, - // Physical address of the 1st level page table - #[cfg(all(target_arch = "x86_64", feature = "common-os"))] - pub root_page_table: usize, } pub(crate) trait TaskFrame { @@ -414,10 +408,7 @@ impl Task { core_id, stacks, object_map, - #[cfg(not(feature = "common-os"))] tls: None, - #[cfg(all(target_arch = "x86_64", feature = "common-os"))] - root_page_table: crate::arch::mm::create_new_root_page_table(), } } @@ -445,7 +436,6 @@ impl Task { stdio::setup(&mut objmap.write()); } - #[cfg(not(feature = "common-os"))] let tls = if cfg!(feature = "instrument-mcount") { Tls::from_env().inspect(Tls::set_thread_ptr) } else { @@ -462,10 +452,7 @@ impl Task { core_id, stacks: TaskStacks::from_boot_stacks(), object_map: OBJECT_MAP.get().unwrap().clone(), - #[cfg(not(feature = "common-os"))] tls, - #[cfg(all(target_arch = "x86_64", feature = "common-os"))] - root_page_table: *crate::scheduler::BOOT_ROOT_PAGE_TABLE.get().unwrap(), } } } diff --git a/src/syscalls/mod.rs b/src/syscalls/mod.rs index 9d5adbb3e6..1ca1a3a395 100644 --- a/src/syscalls/mod.rs +++ b/src/syscalls/mod.rs @@ -1,7 +1,7 @@ #![allow(clippy::result_unit_err)] use alloc::ffi::CString; -#[cfg(all(target_os = "none", not(feature = "common-os")))] +#[cfg(target_os = "none")] use core::alloc::{GlobalAlloc, Layout}; use core::ffi::{CStr, c_char}; use core::marker::PhantomData; @@ -29,7 +29,7 @@ use crate::fd::{ dup_object, dup_object2, get_object, isatty, remove_object, }; use crate::fs::{self, FileAttr, SeekWhence}; -#[cfg(all(target_os = "none", not(feature = "common-os")))] +#[cfg(target_os = "none")] use crate::mm::ALLOCATOR; use crate::{env, init_buf}; @@ -46,8 +46,6 @@ mod semaphore; pub mod socket; mod spinlock; mod system; -#[cfg(feature = "common-os")] -pub(crate) mod table; mod tasks; mod timer; @@ -73,7 +71,7 @@ pub(crate) fn init() { /// Returning a null pointer indicates that either memory is exhausted or /// `size` and `align` do not meet this allocator's size or alignment constraints. /// -#[cfg(all(target_os = "none", not(feature = "common-os")))] +#[cfg(target_os = "none")] #[hermit_macro::system] #[unsafe(no_mangle)] pub extern "C" fn sys_alloc(size: usize, align: usize) -> *mut u8 { @@ -90,7 +88,7 @@ pub extern "C" fn sys_alloc(size: usize, align: usize) -> *mut u8 { ptr } -#[cfg(all(target_os = "none", not(feature = "common-os")))] +#[cfg(target_os = "none")] #[hermit_macro::system] #[unsafe(no_mangle)] pub extern "C" fn sys_alloc_zeroed(size: usize, align: usize) -> *mut u8 { @@ -109,7 +107,7 @@ pub extern "C" fn sys_alloc_zeroed(size: usize, align: usize) -> *mut u8 { ptr } -#[cfg(all(target_os = "none", not(feature = "common-os")))] +#[cfg(target_os = "none")] #[hermit_macro::system] #[unsafe(no_mangle)] pub extern "C" fn sys_malloc(size: usize, align: usize) -> *mut u8 { @@ -145,7 +143,7 @@ pub extern "C" fn sys_malloc(size: usize, align: usize) -> *mut u8 { /// # Errors /// Returns null if the new layout does not meet the size and alignment constraints of the /// allocator, or if reallocation otherwise fails. -#[cfg(all(target_os = "none", not(feature = "common-os")))] +#[cfg(target_os = "none")] #[hermit_macro::system] #[unsafe(no_mangle)] pub unsafe extern "C" fn sys_realloc( @@ -186,7 +184,7 @@ pub unsafe extern "C" fn sys_realloc( /// /// # Errors /// May panic if debug assertions are enabled and invalid parameters `size` or `align` where passed. -#[cfg(all(target_os = "none", not(feature = "common-os")))] +#[cfg(target_os = "none")] #[hermit_macro::system] #[unsafe(no_mangle)] pub unsafe extern "C" fn sys_dealloc(ptr: *mut u8, size: usize, align: usize) { @@ -206,7 +204,7 @@ pub unsafe extern "C" fn sys_dealloc(ptr: *mut u8, size: usize, align: usize) { } } -#[cfg(all(target_os = "none", not(feature = "common-os")))] +#[cfg(target_os = "none")] #[hermit_macro::system] #[unsafe(no_mangle)] pub unsafe extern "C" fn sys_free(ptr: *mut u8, size: usize, align: usize) { diff --git a/src/syscalls/table.rs b/src/syscalls/table.rs deleted file mode 100644 index fcbb32b489..0000000000 --- a/src/syscalls/table.rs +++ /dev/null @@ -1,88 +0,0 @@ -use core::arch::naked_asm; - -use crate::syscalls::*; - -/// Number of the system call `exit` -const SYSNO_EXIT: usize = 0; -/// Number of the system call `write` -const SYSNO_WRITE: usize = 1; -/// Number of the system call `read` -const SYSNO_READ: usize = 2; -/// Number of the system call `usleep` -const SYSNO_USLEEP: usize = 3; -/// Number of the system call `getpid` -const SYSNO_GETPID: usize = 4; -/// Number of the system call `yield` -const SYSNO_YIELD: usize = 5; -/// Number of the system call `read_entropy` -const SYSNO_READ_ENTROPY: usize = 6; -/// Number of the system call `get_processor_count` -const SYSNO_GET_PROCESSOR_COUNT: usize = 7; -/// Number of the system call `close` -const SYSNO_CLOSE: usize = 8; -/// Number of the system call `futex_wait` -const SYSNO_FUTEX_WAIT: usize = 9; -/// Number of the system call `futex_wake` -const SYSNO_FUTEX_WAKE: usize = 10; -/// Number of the system call `open` -const SYSNO_OPEN: usize = 11; -/// Number of the system call `writev` -const SYSNO_WRITEV: usize = 12; -/// Number of the system call `readv` -const SYSNO_READV: usize = 13; - -/// Total number of system calls -const NO_SYSCALLS: usize = 32; - -extern "C" fn invalid_syscall(sys_no: u64) -> ! { - error!("Invalid syscall {sys_no}"); - sys_exit(1); -} - -#[allow(unused_assignments)] -#[unsafe(no_mangle)] -#[unsafe(naked)] -pub(crate) unsafe extern "C" fn sys_invalid() { - naked_asm!( - "mov rdi, rax", - "call {}", - sym invalid_syscall, - ); -} - -#[repr(align(64))] -#[repr(C)] -pub(crate) struct SyscallTable { - handle: [*const usize; NO_SYSCALLS], -} - -impl SyscallTable { - pub const fn new() -> Self { - let mut table = SyscallTable { - handle: [sys_invalid as *const _; NO_SYSCALLS], - }; - - table.handle[SYSNO_EXIT] = sys_exit as *const _; - table.handle[SYSNO_WRITE] = sys_write as *const _; - table.handle[SYSNO_READ] = sys_read as *const _; - table.handle[SYSNO_USLEEP] = sys_usleep as *const _; - table.handle[SYSNO_GETPID] = sys_getpid as *const _; - table.handle[SYSNO_YIELD] = sys_yield as *const _; - table.handle[SYSNO_READ_ENTROPY] = sys_read_entropy as *const _; - table.handle[SYSNO_GET_PROCESSOR_COUNT] = sys_get_processor_count as *const _; - table.handle[SYSNO_CLOSE] = sys_close as *const _; - table.handle[SYSNO_FUTEX_WAIT] = sys_futex_wait as *const _; - table.handle[SYSNO_FUTEX_WAKE] = sys_futex_wake as *const _; - table.handle[SYSNO_OPEN] = sys_open as *const _; - table.handle[SYSNO_READV] = sys_readv as *const _; - table.handle[SYSNO_WRITEV] = sys_writev as *const _; - - table - } -} - -unsafe impl Send for SyscallTable {} -unsafe impl Sync for SyscallTable {} - -#[unsafe(no_mangle)] -pub(crate) static SYSHANDLER_TABLE: SyscallTable = SyscallTable::new(); diff --git a/xtask/src/clippy.rs b/xtask/src/clippy.rs index de1a6997e5..49e2bfb8e4 100644 --- a/xtask/src/clippy.rs +++ b/xtask/src/clippy.rs @@ -19,7 +19,6 @@ impl Clippy { let clippy = || cmd!(sh, "cargo clippy --target={triple} --all-targets"); clippy().run()?; - clippy().arg("--features=common-os").run()?; clippy() .arg("--features=acpi,dns,fsgsbase,pci,smp,vga") .run()?;