diff --git a/src/arch/aarch64/interrupt/exception.rs b/src/arch/aarch64/interrupt/exception.rs index bde5567c6c..4d947e5a41 100644 --- a/src/arch/aarch64/interrupt/exception.rs +++ b/src/arch/aarch64/interrupt/exception.rs @@ -175,7 +175,7 @@ exception_stack!(synchronous_exception_at_el0, |stack| { 0b010101 => { let scratch = &stack.scratch; let ret = syscall::syscall( - scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, stack, + scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, ); stack.scratch.x0 = ret; } diff --git a/src/arch/x86/interrupt/syscall.rs b/src/arch/x86/interrupt/syscall.rs index 5f847a320d..d020daef61 100644 --- a/src/arch/x86/interrupt/syscall.rs +++ b/src/arch/x86/interrupt/syscall.rs @@ -34,7 +34,6 @@ interrupt_stack!(syscall, |stack| { scratch.edx, preserved.esi, preserved.edi, - stack, ); stack.scratch.eax = ret; }) diff --git a/src/arch/x86_64/interrupt/syscall.rs b/src/arch/x86_64/interrupt/syscall.rs index 644d5875ca..55b6d1f4c2 100644 --- a/src/arch/x86_64/interrupt/syscall.rs +++ b/src/arch/x86_64/interrupt/syscall.rs @@ -75,7 +75,6 @@ pub unsafe extern "C" fn __inner_syscall_instruction(stack: *mut InterruptStack) scratch.rdx, scratch.r10, scratch.r8, - &mut *stack, ); (*stack).scratch.rax = ret; } diff --git a/src/context/arch/aarch64.rs b/src/context/arch/aarch64.rs index ca2d45a1ee..fa6e272b62 100644 --- a/src/context/arch/aarch64.rs +++ b/src/context/arch/aarch64.rs @@ -1,7 +1,13 @@ +use crate::{ + arch::{device::cpu::registers::control_regs, interrupt::InterruptStack, paging::PageMapper}, + context::{context::Kstack, memory::Table}, + percpu::PercpuBlock, + syscall::FloatRegisters, +}; use core::{arch::asm, mem, mem::offset_of, ptr, sync::atomic::AtomicBool}; +use rmm::TableKind; use spin::Once; - -use crate::{percpu::PercpuBlock, syscall::FloatRegisters}; +use syscall::{EnvRegisters, Error, Result, ENOMEM}; /// This must be used by the kernel to ensure that context switches are done atomically /// Compare and exchange this to true when beginning a context switch on any CPU @@ -62,23 +68,49 @@ impl Context { } } - pub fn set_stack(&mut self, address: usize) { + fn set_stack(&mut self, address: usize) { self.sp = address; } - pub fn set_x28(&mut self, x28: usize) { + fn set_x28(&mut self, x28: usize) { self.x28 = x28; } - pub fn set_lr(&mut self, address: usize) { + fn set_lr(&mut self, address: usize) { self.lr = address; } - pub fn set_context_handle(&mut self) { + fn set_context_handle(&mut self) { let address = self as *const _ as usize; self.tpidrro_el0 = address; } + pub(crate) fn setup_initial_call( + &mut self, + stack: &Kstack, + func: extern "C" fn(), + userspace_allowed: bool, + ) { + let mut stack_top = stack.initial_top(); + + const INT_REGS_SIZE: usize = core::mem::size_of::(); + + if userspace_allowed { + unsafe { + // Zero-initialize InterruptStack registers. + stack_top = stack_top.sub(INT_REGS_SIZE); + stack_top.write_bytes(0_u8, INT_REGS_SIZE); + (&mut *stack_top.cast::()).init(); + } + } + + self.set_lr(crate::interrupt::syscall::enter_usermode as usize); + self.set_x28(func as usize); + self.set_context_handle(); + + self.set_stack(stack_top as usize); + } + #[allow(unused)] pub fn dump(&self) { println!("elr_el1: 0x{:016x}", self.elr_el1); @@ -131,6 +163,36 @@ impl super::Context { scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, ]) } + + pub(crate) fn write_current_env_regs(&self, regs: EnvRegisters) -> Result<()> { + unsafe { + control_regs::tpidr_el0_write(regs.tpidr_el0 as u64); + control_regs::tpidrro_el0_write(regs.tpidrro_el0 as u64); + } + Ok(()) + } + + pub(crate) fn write_env_regs(&mut self, regs: EnvRegisters) -> Result<()> { + self.arch.tpidr_el0 = regs.tpidr_el0; + self.arch.tpidrro_el0 = regs.tpidrro_el0; + Ok(()) + } + + pub(crate) fn read_current_env_regs(&self) -> Result { + unsafe { + Ok(EnvRegisters { + tpidr_el0: control_regs::tpidr_el0() as usize, + tpidrro_el0: control_regs::tpidrro_el0() as usize, + }) + } + } + + pub(crate) fn read_env_regs(&self) -> Result { + Ok(EnvRegisters { + tpidr_el0: self.arch.tpidr_el0, + tpidrro_el0: self.arch.tpidrro_el0, + }) + } } pub static EMPTY_CR3: Once = Once::new(); @@ -324,3 +386,13 @@ unsafe extern "C" fn switch_to_inner(_prev: &mut Context, _next: &mut Context) { options(noreturn), ); } + +/// Allocates a new empty utable +pub fn setup_new_utable() -> Result { + let utable = unsafe { + PageMapper::create(TableKind::User, crate::memory::TheFrameAllocator) + .ok_or(Error::new(ENOMEM))? + }; + + Ok(Table { utable }) +} diff --git a/src/context/arch/x86.rs b/src/context/arch/x86.rs index 363e0e6823..2e258f9536 100644 --- a/src/context/arch/x86.rs +++ b/src/context/arch/x86.rs @@ -6,8 +6,15 @@ use crate::{ syscall::FloatRegisters, }; +use crate::{ + arch::{interrupt::InterruptStack, paging::PageMapper}, + context::{context::Kstack, memory::Table}, + memory::RmmA, +}; use core::mem::offset_of; +use rmm::{Arch, TableKind, VirtualAddress}; use spin::Once; +use syscall::{error::*, EnvRegisters}; /// This must be used by the kernel to ensure that context switches are done atomically /// Compare and exchange this to true when beginning a context switch on any CPU @@ -62,10 +69,41 @@ impl Context { } } - pub fn set_stack(&mut self, address: usize) { + fn set_stack(&mut self, address: usize) { self.esp = address; } + + pub(crate) fn setup_initial_call( + &mut self, + stack: &Kstack, + func: extern "C" fn(), + userspace_allowed: bool, + ) { + let mut stack_top = stack.initial_top(); + + const INT_REGS_SIZE: usize = core::mem::size_of::(); + + unsafe { + if userspace_allowed { + // Zero-initialize InterruptStack registers. + stack_top = stack_top.sub(INT_REGS_SIZE); + stack_top.write_bytes(0_u8, INT_REGS_SIZE); + (&mut *stack_top.cast::()).init(); + + stack_top = stack_top.sub(core::mem::size_of::()); + stack_top + .cast::() + .write(crate::interrupt::syscall::enter_usermode as usize); + } + + stack_top = stack_top.sub(core::mem::size_of::()); + stack_top.cast::().write(func as usize); + } + + self.set_stack(stack_top as usize); + } } + impl super::Context { pub fn get_fx_regs(&self) -> FloatRegisters { let mut regs = unsafe { self.kfx.as_ptr().cast::().read() }; @@ -121,6 +159,50 @@ impl super::Context { regs.preserved.edi, ]) } + + pub(crate) fn write_current_env_regs(&mut self, regs: EnvRegisters) -> Result<()> { + if RmmA::virt_is_valid(VirtualAddress::new(regs.fsbase as usize)) + && RmmA::virt_is_valid(VirtualAddress::new(regs.gsbase as usize)) + { + unsafe { + (&mut *pcr()).gdt[GDT_USER_FS].set_offset(regs.fsbase); + (&mut *pcr()).gdt[GDT_USER_GS].set_offset(regs.gsbase); + } + self.arch.fsbase = regs.fsbase as usize; + self.arch.gsbase = regs.gsbase as usize; + Ok(()) + } else { + Err(Error::new(EINVAL)) + } + } + + pub(crate) fn write_env_regs(&mut self, regs: EnvRegisters) -> Result<()> { + if RmmA::virt_is_valid(VirtualAddress::new(regs.fsbase as usize)) + && RmmA::virt_is_valid(VirtualAddress::new(regs.gsbase as usize)) + { + self.arch.fsbase = regs.fsbase as usize; + self.arch.gsbase = regs.gsbase as usize; + Ok(()) + } else { + Err(Error::new(EINVAL)) + } + } + + pub(crate) fn read_current_env_regs(&self) -> Result { + unsafe { + Ok(EnvRegisters { + fsbase: (&*pcr()).gdt[GDT_USER_FS].offset(), + gsbase: (&*pcr()).gdt[GDT_USER_GS].offset(), + }) + } + } + + pub(crate) fn read_env_regs(&self) -> Result { + Ok(EnvRegisters { + fsbase: self.arch.fsbase as u32, + gsbase: self.arch.gsbase as u32, + }) + } } pub static EMPTY_CR3: Once = Once::new(); @@ -227,3 +309,33 @@ unsafe extern "cdecl" fn switch_to_inner() { options(noreturn), ); } + +/// Allocates a new identically mapped ktable and empty utable (same memory on x86) +pub fn setup_new_utable() -> Result
{ + use crate::memory::KernelMapper; + + let utable = unsafe { + PageMapper::create(TableKind::User, crate::memory::TheFrameAllocator) + .ok_or(Error::new(ENOMEM))? + }; + + { + let active_ktable = KernelMapper::lock(); + + let copy_mapping = |p4_no| unsafe { + let entry = active_ktable + .table() + .entry(p4_no) + .unwrap_or_else(|| panic!("expected kernel PML {} to be mapped", p4_no)); + + utable.table().set_entry(p4_no, entry) + }; + + // Copy higher half (kernel) mappings + for i in 512..1024 { + copy_mapping(i); + } + } + + Ok(Table { utable }) +} diff --git a/src/context/arch/x86_64.rs b/src/context/arch/x86_64.rs index 2349b4fb13..4ab78d444d 100644 --- a/src/context/arch/x86_64.rs +++ b/src/context/arch/x86_64.rs @@ -5,8 +5,15 @@ use core::{ use crate::syscall::FloatRegisters; +use crate::{ + arch::{interrupt::InterruptStack, paging::PageMapper}, + context::{context::Kstack, memory::Table}, + memory::RmmA, +}; use core::mem::offset_of; +use rmm::{Arch, TableKind, VirtualAddress}; use spin::Once; +use syscall::{error::*, EnvRegisters}; use x86::msr; /// This must be used by the kernel to ensure that context switches are done atomically @@ -74,9 +81,39 @@ impl Context { } } - pub fn set_stack(&mut self, address: usize) { + fn set_stack(&mut self, address: usize) { self.rsp = address; } + + pub(crate) fn setup_initial_call( + &mut self, + stack: &Kstack, + func: extern "C" fn(), + userspace_allowed: bool, + ) { + let mut stack_top = stack.initial_top(); + + const INT_REGS_SIZE: usize = core::mem::size_of::(); + + unsafe { + if userspace_allowed { + // Zero-initialize InterruptStack registers. + stack_top = stack_top.sub(INT_REGS_SIZE); + stack_top.write_bytes(0_u8, INT_REGS_SIZE); + (&mut *stack_top.cast::()).init(); + + stack_top = stack_top.sub(core::mem::size_of::()); + stack_top + .cast::() + .write(crate::interrupt::syscall::enter_usermode as usize); + } + + stack_top = stack_top.sub(core::mem::size_of::()); + stack_top.cast::().write(func as usize); + } + + self.set_stack(stack_top as usize); + } } impl super::Context { pub fn get_fx_regs(&self) -> FloatRegisters { @@ -121,7 +158,7 @@ impl super::Context { } } - pub fn current_syscall(&self) -> Option<[usize; 6]> { + pub(crate) fn current_syscall(&self) -> Option<[usize; 6]> { if !self.inside_syscall { return None; } @@ -136,6 +173,54 @@ impl super::Context { scratch.r8, ]) } + + pub(crate) fn read_current_env_regs(&self) -> Result { + // TODO: Avoid rdmsr if fsgsbase is not enabled, if this is worth optimizing for. + unsafe { + Ok(EnvRegisters { + fsbase: msr::rdmsr(msr::IA32_FS_BASE), + gsbase: msr::rdmsr(msr::IA32_KERNEL_GSBASE), + }) + } + } + + pub(crate) fn read_env_regs(&self) -> Result { + Ok(EnvRegisters { + fsbase: self.arch.fsbase as u64, + gsbase: self.arch.gsbase as u64, + }) + } + + pub(crate) fn write_current_env_regs(&mut self, regs: EnvRegisters) -> Result<()> { + if RmmA::virt_is_valid(VirtualAddress::new(regs.fsbase as usize)) + && RmmA::virt_is_valid(VirtualAddress::new(regs.gsbase as usize)) + { + unsafe { + x86::msr::wrmsr(x86::msr::IA32_FS_BASE, regs.fsbase as u64); + // We have to write to KERNEL_GSBASE, because when the kernel returns to + // userspace, it will have executed SWAPGS first. + x86::msr::wrmsr(x86::msr::IA32_KERNEL_GSBASE, regs.gsbase as u64); + } + self.arch.fsbase = regs.fsbase as usize; + self.arch.gsbase = regs.gsbase as usize; + + Ok(()) + } else { + Err(Error::new(EINVAL)) + } + } + + pub(crate) fn write_env_regs(&mut self, regs: EnvRegisters) -> Result<()> { + if RmmA::virt_is_valid(VirtualAddress::new(regs.fsbase as usize)) + && RmmA::virt_is_valid(VirtualAddress::new(regs.gsbase as usize)) + { + self.arch.fsbase = regs.fsbase as usize; + self.arch.gsbase = regs.gsbase as usize; + Ok(()) + } else { + Err(Error::new(EINVAL)) + } + } } pub static EMPTY_CR3: Once = Once::new(); @@ -302,3 +387,39 @@ unsafe extern "sysv64" fn switch_to_inner(_prev: &mut Context, _next: &mut Conte options(noreturn), ); } + +/// Allocates a new identically mapped ktable and empty utable (same memory on x86_64). +pub fn setup_new_utable() -> Result
{ + use crate::memory::{KernelMapper, TheFrameAllocator}; + + let utable = unsafe { + PageMapper::create(TableKind::User, TheFrameAllocator).ok_or(Error::new(ENOMEM))? + }; + + { + let active_ktable = KernelMapper::lock(); + + let copy_mapping = |p4_no| unsafe { + let entry = active_ktable + .table() + .entry(p4_no) + .unwrap_or_else(|| panic!("expected kernel PML {} to be mapped", p4_no)); + + utable.table().set_entry(p4_no, entry) + }; + // TODO: Just copy all 256 mappings? Or copy KERNEL_PML4+KERNEL_PERCPU_PML4 (needed for + // paranoid ISRs which can occur anywhere; we don't want interrupts to triple fault!) and + // map lazily via page faults in the kernel. + + // Copy kernel image mapping + copy_mapping(crate::KERNEL_PML4); + + // Copy kernel heap mapping + copy_mapping(crate::KERNEL_HEAP_PML4); + + // Copy physmap mapping + copy_mapping(crate::PHYS_PML4); + } + + Ok(Table { utable }) +} diff --git a/src/context/memory.rs b/src/context/memory.rs index f0c2a4369a..615b610801 100644 --- a/src/context/memory.rs +++ b/src/context/memory.rs @@ -12,6 +12,7 @@ use syscall::{error::*, flag::MapFlags, GrantFlags, MunmapFlags}; use crate::{ arch::paging::PAGE_SIZE, + context::arch::setup_new_utable, cpu_set::LogicalCpuSet, memory::{ deallocate_frame, deallocate_p2frame, get_page_info, init_frame, the_zeroed_frame, @@ -2258,84 +2259,6 @@ impl Drop for Table { } } -/// Allocates a new empty utable -#[cfg(target_arch = "aarch64")] -pub fn setup_new_utable() -> Result
{ - let utable = unsafe { - PageMapper::create(TableKind::User, crate::memory::TheFrameAllocator) - .ok_or(Error::new(ENOMEM))? - }; - - Ok(Table { utable }) -} - -/// Allocates a new identically mapped ktable and empty utable (same memory on x86) -#[cfg(target_arch = "x86")] -pub fn setup_new_utable() -> Result
{ - use crate::memory::KernelMapper; - - let utable = unsafe { - PageMapper::create(TableKind::User, crate::memory::TheFrameAllocator) - .ok_or(Error::new(ENOMEM))? - }; - - { - let active_ktable = KernelMapper::lock(); - - let copy_mapping = |p4_no| unsafe { - let entry = active_ktable - .table() - .entry(p4_no) - .unwrap_or_else(|| panic!("expected kernel PML {} to be mapped", p4_no)); - - utable.table().set_entry(p4_no, entry) - }; - - // Copy higher half (kernel) mappings - for i in 512..1024 { - copy_mapping(i); - } - } - - Ok(Table { utable }) -} - -/// Allocates a new identically mapped ktable and empty utable (same memory on x86_64). -#[cfg(target_arch = "x86_64")] -pub fn setup_new_utable() -> Result
{ - use crate::memory::{KernelMapper, TheFrameAllocator}; - - let utable = unsafe { - PageMapper::create(TableKind::User, TheFrameAllocator).ok_or(Error::new(ENOMEM))? - }; - - { - let active_ktable = KernelMapper::lock(); - - let copy_mapping = |p4_no| unsafe { - let entry = active_ktable - .table() - .entry(p4_no) - .unwrap_or_else(|| panic!("expected kernel PML {} to be mapped", p4_no)); - - utable.table().set_entry(p4_no, entry) - }; - // TODO: Just copy all 256 mappings? Or copy KERNEL_PML4+KERNEL_PERCPU_PML4 (needed for - // paranoid ISRs which can occur anywhere; we don't want interrupts to triple fault!) and - // map lazily via page faults in the kernel. - - // Copy kernel image mapping - copy_mapping(crate::KERNEL_PML4); - - // Copy kernel heap mapping - copy_mapping(crate::KERNEL_HEAP_PML4); - - // Copy physmap mapping - copy_mapping(crate::PHYS_PML4); - } - - Ok(Table { utable }) -} #[derive(Clone, Copy, PartialEq)] pub enum AccessMode { Read, diff --git a/src/context/mod.rs b/src/context/mod.rs index 0cc586d7d2..436ea0e7cd 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -11,7 +11,6 @@ use syscall::ENOMEM; use crate::{ context::memory::AddrSpaceWrapper, cpu_set::LogicalCpuSet, - interrupt::InterruptStack, paging::{RmmA, RmmArch, TableKind}, percpu::PercpuBlock, sync::WaitMap, @@ -182,42 +181,9 @@ pub fn spawn( { let mut context = context_lock.write(); let _ = context.set_addr_space(Some(AddrSpaceWrapper::new()?)); - - let mut stack_top = stack.initial_top(); - - const INT_REGS_SIZE: usize = core::mem::size_of::(); - - if userspace_allowed { - unsafe { - // Zero-initialize InterruptStack registers. - stack_top = stack_top.sub(INT_REGS_SIZE); - stack_top.write_bytes(0_u8, INT_REGS_SIZE); - (&mut *stack_top.cast::()).init(); - } - } - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] - unsafe { - if userspace_allowed { - stack_top = stack_top.sub(core::mem::size_of::()); - stack_top - .cast::() - .write(crate::interrupt::syscall::enter_usermode as usize); - } - - stack_top = stack_top.sub(core::mem::size_of::()); - stack_top.cast::().write(func as usize); - } - - #[cfg(target_arch = "aarch64")] - { - context - .arch - .set_lr(crate::interrupt::syscall::enter_usermode as usize); - context.arch.set_x28(func as usize); - context.arch.set_context_handle(); - } - - context.arch.set_stack(stack_top as usize); + context + .arch + .setup_initial_call(&stack, func, userspace_allowed); context.kstack = Some(stack); context.userspace = userspace_allowed; diff --git a/src/scheme/mod.rs b/src/scheme/mod.rs index d358cfb663..7703d8efcf 100644 --- a/src/scheme/mod.rs +++ b/src/scheme/mod.rs @@ -356,7 +356,7 @@ impl SchemeList { } } for name in remove { - assert!(names.remove(&name).is_some()); + assert!(names.swap_remove(&name).is_some()); } } } diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index d83e2264a4..a60a686f1b 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -1630,147 +1630,19 @@ impl ContextHandle { } } } -#[cfg(target_arch = "aarch64")] + fn write_env_regs(context: Arc>, regs: EnvRegisters) -> Result<()> { - use crate::device::cpu::registers::control_regs; - if context::is_current(&context) { - unsafe { - control_regs::tpidr_el0_write(regs.tpidr_el0 as u64); - control_regs::tpidrro_el0_write(regs.tpidrro_el0 as u64); - } + context::current().write().write_current_env_regs(regs) } else { - try_stop_context(context, |context| { - context.arch.tpidr_el0 = regs.tpidr_el0; - context.arch.tpidrro_el0 = regs.tpidrro_el0; - Ok(()) - })?; + try_stop_context(context, |context| context.write_env_regs(regs)) } - Ok(()) } -#[cfg(target_arch = "x86")] -fn write_env_regs(context: Arc>, regs: EnvRegisters) -> Result<()> { - if !(RmmA::virt_is_valid(VirtualAddress::new(regs.fsbase as usize)) - && RmmA::virt_is_valid(VirtualAddress::new(regs.gsbase as usize))) - { - return Err(Error::new(EINVAL)); - } - +fn read_env_regs(context: Arc>) -> Result { if context::is_current(&context) { - unsafe { - (&mut *crate::gdt::pcr()).gdt[crate::gdt::GDT_USER_FS].set_offset(regs.fsbase); - (&mut *crate::gdt::pcr()).gdt[crate::gdt::GDT_USER_GS].set_offset(regs.gsbase); - - match context.write().arch { - ref mut arch => { - arch.fsbase = regs.fsbase as usize; - arch.gsbase = regs.gsbase as usize; - } - } - } + context::current().read().read_current_env_regs() } else { - try_stop_context(context, |context| { - context.arch.fsbase = regs.fsbase as usize; - context.arch.gsbase = regs.gsbase as usize; - Ok(()) - })?; + try_stop_context(context, |context| context.read_env_regs()) } - Ok(()) -} - -#[cfg(target_arch = "x86_64")] -fn write_env_regs(context: Arc>, regs: EnvRegisters) -> Result<()> { - use crate::memory::RmmA; - use rmm::Arch; - if !(RmmA::virt_is_valid(VirtualAddress::new(regs.fsbase as usize)) - && RmmA::virt_is_valid(VirtualAddress::new(regs.gsbase as usize))) - { - return Err(Error::new(EINVAL)); - } - - if context::is_current(&context) { - unsafe { - x86::msr::wrmsr(x86::msr::IA32_FS_BASE, regs.fsbase as u64); - // We have to write to KERNEL_GSBASE, because when the kernel returns to - // userspace, it will have executed SWAPGS first. - x86::msr::wrmsr(x86::msr::IA32_KERNEL_GSBASE, regs.gsbase as u64); - - match context::current().write().arch { - ref mut arch => { - arch.fsbase = regs.fsbase as usize; - arch.gsbase = regs.gsbase as usize; - } - } - } - } else { - try_stop_context(context, |context| { - context.arch.fsbase = regs.fsbase as usize; - context.arch.gsbase = regs.gsbase as usize; - Ok(()) - })?; - } - Ok(()) -} -#[cfg(target_arch = "aarch64")] -fn read_env_regs(context: Arc>) -> Result { - use crate::device::cpu::registers::control_regs; - - let (tpidr_el0, tpidrro_el0) = if context::is_current(&context) { - unsafe { - ( - control_regs::tpidr_el0() as usize, - control_regs::tpidrro_el0() as usize, - ) - } - } else { - try_stop_context(context, |context| { - Ok((context.arch.tpidr_el0, context.arch.tpidrro_el0)) - })? - }; - Ok(EnvRegisters { - tpidr_el0, - tpidrro_el0, - }) -} - -#[cfg(target_arch = "x86")] -fn read_env_regs(context: Arc>) -> Result { - let (fsbase, gsbase) = if context::is_current(&context) { - unsafe { - ( - (&*crate::gdt::pcr()).gdt[crate::gdt::GDT_USER_FS].offset() as u64, - (&*crate::gdt::pcr()).gdt[crate::gdt::GDT_USER_GS].offset() as u64, - ) - } - } else { - try_stop_context(context, |context| { - Ok((context.arch.fsbase as u64, context.arch.gsbase as u64)) - })? - }; - Ok(EnvRegisters { - fsbase: fsbase as _, - gsbase: gsbase as _, - }) -} - -#[cfg(target_arch = "x86_64")] -fn read_env_regs(context: Arc>) -> Result { - // TODO: Avoid rdmsr if fsgsbase is not enabled, if this is worth optimizing for. - let (fsbase, gsbase) = if context::is_current(&context) { - unsafe { - ( - x86::msr::rdmsr(x86::msr::IA32_FS_BASE), - x86::msr::rdmsr(x86::msr::IA32_KERNEL_GSBASE), - ) - } - } else { - try_stop_context(context, |context| { - Ok((context.arch.fsbase as u64, context.arch.gsbase as u64)) - })? - }; - Ok(EnvRegisters { - fsbase: fsbase as _, - gsbase: gsbase as _, - }) } diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs index 6ac1bfa1ee..6ebcaa570e 100644 --- a/src/syscall/mod.rs +++ b/src/syscall/mod.rs @@ -24,7 +24,7 @@ use self::{ usercopy::UserSlice, }; -use crate::{interrupt::InterruptStack, percpu::PercpuBlock}; +use crate::percpu::PercpuBlock; use crate::{ context::{memory::AddrSpace, process::ProcessId}, @@ -60,15 +60,8 @@ pub mod usercopy; /// This function is the syscall handler of the kernel, it is composed of an inner function that returns a `Result`. After the inner function runs, the syscall /// function calls [`Error::mux`] on it. -pub fn syscall( - a: usize, - b: usize, - c: usize, - d: usize, - e: usize, - f: usize, - _stack: &mut InterruptStack, -) -> usize { +#[must_use] +pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> usize { #[inline(always)] fn inner(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> Result { let fd = FileHandle::from(b);