diff --git a/src/arch/aarch64/interrupt/handler.rs b/src/arch/aarch64/interrupt/handler.rs index 1aa74b296e..815e55828a 100644 --- a/src/arch/aarch64/interrupt/handler.rs +++ b/src/arch/aarch64/interrupt/handler.rs @@ -113,9 +113,7 @@ pub struct InterruptStack { } impl InterruptStack { - pub fn setup_minimal(&mut self, ip: usize, _singlestep: bool) { - self.set_instr_pointer(ip); - } + pub fn init(&mut self) {} pub fn set_stack_pointer(&mut self, sp: usize) { self.iret.sp_el0 = sp; } @@ -405,6 +403,7 @@ macro_rules! exception_stack { #[naked] pub unsafe extern "C" fn enter_usermode() -> ! { core::arch::asm!(concat!( + "blr x28\n", // Restore all userspace registers pop_special!(), pop_scratch!(), diff --git a/src/arch/aarch64/start.rs b/src/arch/aarch64/start.rs index d8543f561d..d2f64c99e0 100644 --- a/src/arch/aarch64/start.rs +++ b/src/arch/aarch64/start.rs @@ -218,19 +218,3 @@ pub struct KernelArgsAp { pub unsafe extern "C" fn kstart_ap(args_ptr: *const KernelArgsAp) -> ! { loop {} } - -#[naked] -//TODO: AbiCompatBool -//TODO: clear all regs? -pub unsafe extern "C" fn usermode(_ip: usize, _sp: usize, _arg: usize, _is_singlestep: usize) -> ! { - core::arch::asm!( - " - msr spsr_el1, xzr // spsr - msr elr_el1, x0 // ip - msr sp_el0, x1 // sp - mov x0, x2 // arg - eret - ", - options(noreturn), - ); -} diff --git a/src/context/arch/aarch64.rs b/src/context/arch/aarch64.rs index 15ce949788..13513b2590 100644 --- a/src/context/arch/aarch64.rs +++ b/src/context/arch/aarch64.rs @@ -80,6 +80,10 @@ impl Context { self.sp = address; } + pub fn set_x28(&mut self, x28: usize) { + self.x28 = x28; + } + pub fn set_lr(&mut self, address: usize) { self.lr = address; } diff --git a/src/context/list.rs b/src/context/list.rs index 98ab2f482d..2e1be989e5 100644 --- a/src/context/list.rs +++ b/src/context/list.rs @@ -117,14 +117,19 @@ impl ContextList { let mut stack_top = unsafe { stack.as_mut_ptr().add(KSTACK_SIZE) }; - unsafe { - if userspace_allowed { + const INT_REGS_SIZE: usize = core::mem::size_of::(); + + if userspace_allowed { + unsafe { // Zero-initialize InterruptStack registers. - const INT_REGS_SIZE: usize = core::mem::size_of::(); 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); } @@ -134,8 +139,9 @@ impl ContextList { } #[cfg(target_arch = "aarch64")] - { - context.arch.set_lr(func as usize); + unsafe { + context.arch.set_lr(crate::interrupt::syscall::enter_usermode as usize); + context.arch.set_x28(func as usize); context.arch.set_context_handle(); }