From e757653fd258668fc6a858689103a9ca76b19d9a Mon Sep 17 00:00:00 2001 From: Allen Aboytes Date: Fri, 12 Apr 2024 17:10:09 -0700 Subject: [PATCH 1/3] Make sure new threads start with interrupts enabled --- src/kernel/src/arch/aarch64/thread.rs | 34 +++++++++++++++++---------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/kernel/src/arch/aarch64/thread.rs b/src/kernel/src/arch/aarch64/thread.rs index 55260812..e6c5ddf2 100644 --- a/src/kernel/src/arch/aarch64/thread.rs +++ b/src/kernel/src/arch/aarch64/thread.rs @@ -16,7 +16,7 @@ use twizzler_abi::upcall::{UpcallFrame, UpcallInfo, UpcallTarget}; use crate::thread::Thread; use crate::memory::VirtAddr; -use super::{exception::ExceptionContext, syscall::Armv8SyscallContext}; +use super::{exception::ExceptionContext, syscall::Armv8SyscallContext, interrupt::DAIFMaskBits}; #[derive(Copy, Clone)] pub enum Registers { @@ -48,6 +48,8 @@ struct RegisterContext { // thread local storage for user space tpidr: u64, tpidrro: u64, + // interrupt state + daif: u64, } // arch specific thread state @@ -62,7 +64,7 @@ unsafe impl Send for ArchThread {} impl ArchThread { pub fn new() -> Self { Self { - context: RegisterContext::default() + context: RegisterContext::default(), } } } @@ -149,12 +151,14 @@ impl Thread { // save the fp (x29) and the lr (x30) "stp x29, x30, [x11, #16 * 5]", // save stack pointer - "mov x15, sp", + "mov x12, sp", // save the thread pointer registers - "mrs x14, tpidr_el0", - "mrs x13, tpidrro_el0", - "stp x15, x14, [x11, #16 * 6]", - "str x13, [x11, #16 * 7]", + "mrs x13, tpidr_el0", + "mrs x14, tpidrro_el0", + // save the current interrupt state + "mrs x15, daif", + "stp x12, x13, [x11, #16 * 6]", + "stp x14, x15, [x11, #16 * 7]", // (2) restore next thread's regs "ldp x19, x20, [x10, #16 * 0]", "ldp x21, x22, [x10, #16 * 1]", @@ -163,12 +167,15 @@ impl Thread { "ldp x27, x28, [x10, #16 * 4]", // restore the fp (x29) and the lr (x30) "ldp x29, x30, [x10, #16 * 5]", + // restore the thread pointer registers + "ldp x12, x13, [x10, #16 * 6]", + "ldp x14, x15, [x10, #16 * 7]", + "msr tpidr_el0, x13", + "msr tpidrro_el0, x14", // (3) switch thread stacks - "ldp x15, x14, [x10, #16 * 6]", - "ldr x13, [x10, #16 * 7]", - "msr tpidr_el0, x14", - "msr tpidrro_el0, x13", - "mov sp, x15", + "mov sp, x12", + // set the current interrupt state + "msr daif, x15", // (4) execution resumes in the address // pointed to by the link register (x30) "ret", @@ -190,5 +197,8 @@ impl Thread { self.arch.context.sp = stack as u64; // set the link register as the second to last entry (x30) self.arch.context.lr = entry as u64; + // by default interrupts are enabled (unmask the I bit) + // in other words set bits D,A, and F in DAIF[9:6] + self.arch.context.daif = (DAIFMaskBits::IRQ.complement().bits() as u64) << 6; } } From 74be249a58872a6f466fbab4f9c0cf20438da79e Mon Sep 17 00:00:00 2001 From: Allen Aboytes Date: Fri, 12 Apr 2024 17:10:51 -0700 Subject: [PATCH 2/3] Enable the system timer --- src/kernel/src/arch/aarch64/interrupt.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kernel/src/arch/aarch64/interrupt.rs b/src/kernel/src/arch/aarch64/interrupt.rs index d346eaf1..cf8eff77 100644 --- a/src/kernel/src/arch/aarch64/interrupt.rs +++ b/src/kernel/src/arch/aarch64/interrupt.rs @@ -197,6 +197,7 @@ pub fn init_interrupts() { PhysicalTimer::INTERRUPT_ID, cpu.id, ); + INTERRUPT_CONTROLLER.enable_interrupt(PhysicalTimer::INTERRUPT_ID); } pub fn set_interrupt( From 3809cfaef85c582aeb440ba4b1c40c7fa16ebdf7 Mon Sep 17 00:00:00 2001 From: Allen Aboytes Date: Fri, 12 Apr 2024 17:12:18 -0700 Subject: [PATCH 3/3] Enable interrupts during synchronous exception handling --- src/kernel/src/arch/aarch64/exception.rs | 13 +++++-------- src/kernel/src/arch/aarch64/syscall.rs | 12 +++++------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/kernel/src/arch/aarch64/exception.rs b/src/kernel/src/arch/aarch64/exception.rs index 7a21e07b..52723e42 100644 --- a/src/kernel/src/arch/aarch64/exception.rs +++ b/src/kernel/src/arch/aarch64/exception.rs @@ -163,10 +163,6 @@ impl From for UpcallFrame { } } -// TODO: reentrant/nested interrupt support -// x save spsr_el1 and elr_el1 before calling handler -// - enable interrupts while servicing exceptions - /// macro creates a high level exception handler /// to be used in the exception vector table. /// saves/restores regs on the current stack pointer @@ -432,7 +428,7 @@ fn sync_handler(ctx: &mut ExceptionContext) { todo!("Permission fault, level {} {:?} {:?}", level, cause, far_va); } crate::thread::enter_kernel(); - // crate::interrupt::set(true); + crate::interrupt::set(true); let elr = ctx.elr; if let Ok(elr_va) = VirtAddr::new(elr) { crate::memory::context::virtmem::page_fault( @@ -444,7 +440,7 @@ fn sync_handler(ctx: &mut ExceptionContext) { } else { todo!("send upcall exception info"); } - // crate::interrupt::set(false); + crate::interrupt::set(false); crate::thread::exit_kernel(); }, Some(ESR_EL1::EC::Value::InstrAbortLowerEL) => { @@ -463,6 +459,7 @@ fn sync_handler(ctx: &mut ExceptionContext) { debug_handler(ctx) }, } + crate::interrupt::post_interrupt(); } fn handle_inst_abort(ctx: &mut ExceptionContext, esr_reg: &InMemoryRegister) { @@ -503,7 +500,7 @@ fn handle_inst_abort(ctx: &mut ExceptionContext, esr_reg: &InMemoryRegister ! { // set the stack pointer SP_EL0.set(context.sp); - // TODO: enable interrupts when we can support nested exception handling - // crate::interrupt::set(true); - // configure the execution state for EL0: // - interrupts unmasked // - el0 exception level @@ -130,9 +127,6 @@ pub unsafe fn return_to_user(context: &Armv8SyscallContext) -> ! { /// Service a system call according to the ABI defined in [`twizzler_abi`] pub fn handle_syscall(ctx: &mut ExceptionContext) { - crate::thread::enter_kernel(); - crate::interrupt::set(true); - let mut context: Armv8SyscallContext = Default::default(); context.x0 = ctx.x0; context.x1 = ctx.x1; @@ -145,8 +139,12 @@ pub fn handle_syscall(ctx: &mut ExceptionContext) { context.sp = ctx.sp; context.elr = ctx.elr; + crate::thread::enter_kernel(); + crate::interrupt::set(true); + crate::syscall::syscall_entry(&mut context); - // crate::interrupt::set(false); + + crate::interrupt::set(false); crate::thread::exit_kernel(); // copy over result values to exception return context