From 12322670cba4ff85d5b3e0c1b15d32c5fede1422 Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Wed, 25 Jan 2023 17:09:29 +0100 Subject: Kernel: Use InterruptsState abstraction in execve.cpp This was using the x86_64 specific cpu_flags abstraction, which is not compatible with aarch64. --- Kernel/Process.cpp | 4 ++-- Kernel/Process.h | 4 ++-- Kernel/Syscalls/execve.cpp | 28 +++++++++++++++++----------- 3 files changed, 21 insertions(+), 15 deletions(-) (limited to 'Kernel') diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index dc77437443..c470168a84 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -246,8 +246,8 @@ ErrorOr> Process::try_create_user_process(LockRefPtr< })); Thread* new_main_thread = nullptr; - u32 prev_flags = 0; - if (auto result = process->exec(move(path_string), move(arguments), move(environment), new_main_thread, prev_flags); result.is_error()) { + InterruptsState previous_interrupts_state = InterruptsState::Enabled; + if (auto result = process->exec(move(path_string), move(arguments), move(environment), new_main_thread, previous_interrupts_state); result.is_error()) { dbgln("Failed to exec {}: {}", path, result.error()); first_thread = nullptr; return result.release_error(); diff --git a/Kernel/Process.h b/Kernel/Process.h index 72f65b004c..aaee9f7787 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -476,7 +476,7 @@ public: NonnullOwnPtrVector const& arguments() const { return m_arguments; }; NonnullOwnPtrVector const& environment() const { return m_environment; }; - ErrorOr exec(NonnullOwnPtr path, NonnullOwnPtrVector arguments, NonnullOwnPtrVector environment, Thread*& new_main_thread, u32& prev_flags, int recursion_depth = 0); + ErrorOr exec(NonnullOwnPtr path, NonnullOwnPtrVector arguments, NonnullOwnPtrVector environment, Thread*& new_main_thread, InterruptsState& previous_interrupts_state, int recursion_depth = 0); ErrorOr load(NonnullLockRefPtr main_program_description, LockRefPtr interpreter_description, const ElfW(Ehdr) & main_program_header); @@ -608,7 +608,7 @@ private: bool create_perf_events_buffer_if_needed(); void delete_perf_events_buffer(); - ErrorOr do_exec(NonnullLockRefPtr main_program_description, NonnullOwnPtrVector arguments, NonnullOwnPtrVector environment, LockRefPtr interpreter_description, Thread*& new_main_thread, u32& prev_flags, const ElfW(Ehdr) & main_program_header); + ErrorOr do_exec(NonnullLockRefPtr main_program_description, NonnullOwnPtrVector arguments, NonnullOwnPtrVector environment, LockRefPtr interpreter_description, Thread*& new_main_thread, InterruptsState& previous_interrupts_state, const ElfW(Ehdr) & main_program_header); ErrorOr do_write(OpenFileDescription&, UserOrKernelBuffer const&, size_t, Optional = {}); ErrorOr do_statvfs(FileSystem const& path, Custody const*, statvfs* buf); diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 865441948b..b9020e86ab 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -467,7 +467,7 @@ void Process::clear_signal_handlers_for_exec() } ErrorOr Process::do_exec(NonnullLockRefPtr main_program_description, NonnullOwnPtrVector arguments, NonnullOwnPtrVector environment, - LockRefPtr interpreter_description, Thread*& new_main_thread, u32& prev_flags, const ElfW(Ehdr) & main_program_header) + LockRefPtr interpreter_description, Thread*& new_main_thread, InterruptsState& previous_interrupts_state, const ElfW(Ehdr) & main_program_header) { VERIFY(is_user_process()); VERIFY(!Processor::in_critical()); @@ -657,10 +657,10 @@ ErrorOr Process::do_exec(NonnullLockRefPtr main_progr // We enter a critical section here because we don't want to get interrupted between do_exec() // and Processor::assume_context() or the next context switch. - // If we used an InterruptDisabler that sti()'d on exit, we might timer tick'd too soon in exec(). + // If we used an InterruptDisabler that calls enable_interrupts() on exit, we might timer tick'd too soon in exec(). Processor::enter_critical(); - prev_flags = cpu_flags(); - cli(); + previous_interrupts_state = processor_interrupts_state(); + Processor::disable_interrupts(); // NOTE: Be careful to not trigger any page faults below! @@ -841,7 +841,7 @@ ErrorOr> Process::find_elf_interpreter_for_execu return nullptr; } -ErrorOr Process::exec(NonnullOwnPtr path, NonnullOwnPtrVector arguments, NonnullOwnPtrVector environment, Thread*& new_main_thread, u32& prev_flags, int recursion_depth) +ErrorOr Process::exec(NonnullOwnPtr path, NonnullOwnPtrVector arguments, NonnullOwnPtrVector environment, Thread*& new_main_thread, InterruptsState& previous_interrupts_state, int recursion_depth) { if (recursion_depth > 2) { dbgln("exec({}): SHENANIGANS! recursed too far trying to find #! interpreter", path); @@ -879,7 +879,7 @@ ErrorOr Process::exec(NonnullOwnPtr path, NonnullOwnPtrVector Process::exec(NonnullOwnPtr path, NonnullOwnPtrVectorview(), *main_program_header, nread, metadata.size)); - return do_exec(move(description), move(arguments), move(environment), move(interpreter_description), new_main_thread, prev_flags, *main_program_header); + return do_exec(move(description), move(arguments), move(environment), move(interpreter_description), new_main_thread, previous_interrupts_state, *main_program_header); } ErrorOr Process::sys$execve(Userspace user_params) @@ -903,7 +903,7 @@ ErrorOr Process::sys$execve(Userspace TRY(require_promise(Pledge::exec)); Thread* new_main_thread = nullptr; - u32 prev_flags = 0; + InterruptsState previous_interrupts_state = InterruptsState::Enabled; // NOTE: Be extremely careful with allocating any kernel memory in this function. // On success, the kernel stack will be lost. @@ -945,7 +945,7 @@ ErrorOr Process::sys$execve(Userspace NonnullOwnPtrVector environment; TRY(copy_user_strings(params.environment, environment)); - TRY(exec(move(path), move(arguments), move(environment), new_main_thread, prev_flags)); + TRY(exec(move(path), move(arguments), move(environment), new_main_thread, previous_interrupts_state)); } // NOTE: If we're here, the exec has succeeded and we've got a new executable image! @@ -964,15 +964,21 @@ ErrorOr Process::sys$execve(Userspace VERIFY(Processor::in_critical() == 1); g_scheduler_lock.lock(); current_thread->set_state(Thread::State::Running); +#if ARCH(X86_64) + FlatPtr prev_flags = previous_interrupts_state == InterruptsState::Enabled ? 0x200 : 0; Processor::assume_context(*current_thread, prev_flags); VERIFY_NOT_REACHED(); +#elif ARCH(AARCH64) + TODO_AARCH64(); +#else +# error Unknown architecture +#endif } // NOTE: This code path is taken in the non-syscall case, i.e when the kernel spawns // a userspace process directly (such as /bin/SystemServer on startup) - if (prev_flags & 0x200) - sti(); + restore_processor_interrupts_state(previous_interrupts_state); Processor::leave_critical(); return 0; } -- cgit v1.2.3