From 3f05748c0c83665de25244cd61da536d03004155 Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Mon, 30 Jan 2023 11:13:20 +0100 Subject: [PATCH] Kernel/aarch64: Store Saved Program Status Register in ThreadRegisters This allows us to set the Mode field of the Saved Program Status Register (EL1) to EL0t when a userspace process is created. --- Kernel/Arch/aarch64/Processor.cpp | 14 +------------- Kernel/Arch/aarch64/ThreadRegisters.h | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/Kernel/Arch/aarch64/Processor.cpp b/Kernel/Arch/aarch64/Processor.cpp index c97d1ef4cf..16b51619e8 100644 --- a/Kernel/Arch/aarch64/Processor.cpp +++ b/Kernel/Arch/aarch64/Processor.cpp @@ -243,19 +243,7 @@ FlatPtr Processor::init_context(Thread& thread, bool leave_crit) eretframe.elr_el1 = thread_regs.elr_el1; eretframe.sp_el0 = kernel_stack_top; eretframe.tpidr_el0 = 0; // FIXME: Correctly initialize this when aarch64 has support for thread local storage. - - Aarch64::SPSR_EL1 saved_program_status_register_el1 = {}; - - // Don't mask any interrupts, so all interrupts are enabled when transfering into the new context - saved_program_status_register_el1.D = 0; - saved_program_status_register_el1.A = 0; - saved_program_status_register_el1.I = 0; - saved_program_status_register_el1.F = 0; - - // Set exception origin mode to EL1h, so when the context is restored, we'll be executing in EL1 with SP_EL1 - // FIXME: This must be EL0t when aarch64 supports userspace applications. - saved_program_status_register_el1.M = Aarch64::SPSR_EL1::Mode::EL1h; - memcpy(&eretframe.spsr_el1, &saved_program_status_register_el1, sizeof(u64)); + eretframe.spsr_el1 = thread_regs.spsr_el1; // Push a TrapFrame onto the stack stack_top -= sizeof(TrapFrame); diff --git a/Kernel/Arch/aarch64/ThreadRegisters.h b/Kernel/Arch/aarch64/ThreadRegisters.h index 9d1f6b0c48..64402113c0 100644 --- a/Kernel/Arch/aarch64/ThreadRegisters.h +++ b/Kernel/Arch/aarch64/ThreadRegisters.h @@ -8,11 +8,13 @@ #include #include +#include namespace Kernel { struct ThreadRegisters { u64 x[31]; + u64 spsr_el1; u64 elr_el1; u64 sp_el0; u64 ttbr0_el1; @@ -26,6 +28,7 @@ struct ThreadRegisters { { set_sp(kernel_stack_top); ttbr0_el1 = space.page_directory().ttbr0(); + set_spsr_el1(); } void set_entry_function(FlatPtr entry_ip, FlatPtr entry_data) @@ -41,6 +44,22 @@ struct ThreadRegisters { (void)space; TODO_AARCH64(); } + + void set_spsr_el1() + { + Aarch64::SPSR_EL1 saved_program_status_register_el1 = {}; + + // Don't mask any interrupts, so all interrupts are enabled when transfering into the new context + saved_program_status_register_el1.D = 0; + saved_program_status_register_el1.A = 0; + saved_program_status_register_el1.I = 0; + saved_program_status_register_el1.F = 0; + + // Set exception origin mode to EL1h, so when the context is restored, we'll be executing in EL1 with SP_EL1 + // FIXME: This must be EL0t when aarch64 supports userspace applications. + saved_program_status_register_el1.M = Aarch64::SPSR_EL1::Mode::EL1h; + memcpy(&spsr_el1, &saved_program_status_register_el1, sizeof(u64)); + } }; }