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.
This commit is contained in:
Timon Kruiper 2023-01-30 11:13:20 +01:00 committed by Linus Groh
parent 816076f71a
commit 3f05748c0c
2 changed files with 20 additions and 13 deletions

View file

@ -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);

View file

@ -8,11 +8,13 @@
#include <AK/Types.h>
#include <Kernel/Memory/AddressSpace.h>
#include <Kernel/StdLib.h>
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));
}
};
}