summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorTimon Kruiper <timonkruiper@gmail.com>2023-01-25 17:09:29 +0100
committerLinus Groh <mail@linusgroh.de>2023-01-27 20:47:08 +0000
commit12322670cba4ff85d5b3e0c1b15d32c5fede1422 (patch)
tree4328c853a3143348654377fe013d0270402d06c5 /Kernel
parent5ffd53e2f22e0c99a99acc900e64bc64b7d6114d (diff)
downloadserenity-12322670cba4ff85d5b3e0c1b15d32c5fede1422.zip
Kernel: Use InterruptsState abstraction in execve.cpp
This was using the x86_64 specific cpu_flags abstraction, which is not compatible with aarch64.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Process.cpp4
-rw-r--r--Kernel/Process.h4
-rw-r--r--Kernel/Syscalls/execve.cpp28
3 files changed, 21 insertions, 15 deletions
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<NonnullLockRefPtr<Process>> 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<KString> const& arguments() const { return m_arguments; };
NonnullOwnPtrVector<KString> const& environment() const { return m_environment; };
- ErrorOr<void> exec(NonnullOwnPtr<KString> path, NonnullOwnPtrVector<KString> arguments, NonnullOwnPtrVector<KString> environment, Thread*& new_main_thread, u32& prev_flags, int recursion_depth = 0);
+ ErrorOr<void> exec(NonnullOwnPtr<KString> path, NonnullOwnPtrVector<KString> arguments, NonnullOwnPtrVector<KString> environment, Thread*& new_main_thread, InterruptsState& previous_interrupts_state, int recursion_depth = 0);
ErrorOr<LoadResult> load(NonnullLockRefPtr<OpenFileDescription> main_program_description, LockRefPtr<OpenFileDescription> 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<void> do_exec(NonnullLockRefPtr<OpenFileDescription> main_program_description, NonnullOwnPtrVector<KString> arguments, NonnullOwnPtrVector<KString> environment, LockRefPtr<OpenFileDescription> interpreter_description, Thread*& new_main_thread, u32& prev_flags, const ElfW(Ehdr) & main_program_header);
+ ErrorOr<void> do_exec(NonnullLockRefPtr<OpenFileDescription> main_program_description, NonnullOwnPtrVector<KString> arguments, NonnullOwnPtrVector<KString> environment, LockRefPtr<OpenFileDescription> interpreter_description, Thread*& new_main_thread, InterruptsState& previous_interrupts_state, const ElfW(Ehdr) & main_program_header);
ErrorOr<FlatPtr> do_write(OpenFileDescription&, UserOrKernelBuffer const&, size_t, Optional<off_t> = {});
ErrorOr<FlatPtr> 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<void> Process::do_exec(NonnullLockRefPtr<OpenFileDescription> main_program_description, NonnullOwnPtrVector<KString> arguments, NonnullOwnPtrVector<KString> environment,
- LockRefPtr<OpenFileDescription> interpreter_description, Thread*& new_main_thread, u32& prev_flags, const ElfW(Ehdr) & main_program_header)
+ LockRefPtr<OpenFileDescription> 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<void> Process::do_exec(NonnullLockRefPtr<OpenFileDescription> 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<LockRefPtr<OpenFileDescription>> Process::find_elf_interpreter_for_execu
return nullptr;
}
-ErrorOr<void> Process::exec(NonnullOwnPtr<KString> path, NonnullOwnPtrVector<KString> arguments, NonnullOwnPtrVector<KString> environment, Thread*& new_main_thread, u32& prev_flags, int recursion_depth)
+ErrorOr<void> Process::exec(NonnullOwnPtr<KString> path, NonnullOwnPtrVector<KString> arguments, NonnullOwnPtrVector<KString> 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<void> Process::exec(NonnullOwnPtr<KString> path, NonnullOwnPtrVector<KSt
auto shebang_path = TRY(shebang_words.first().try_clone());
arguments.ptr_at(0) = move(path);
TRY(arguments.try_prepend(move(shebang_words)));
- return exec(move(shebang_path), move(arguments), move(environment), new_main_thread, prev_flags, ++recursion_depth);
+ return exec(move(shebang_path), move(arguments), move(environment), new_main_thread, previous_interrupts_state, ++recursion_depth);
}
// #2) ELF32 for i386
@@ -894,7 +894,7 @@ ErrorOr<void> Process::exec(NonnullOwnPtr<KString> path, NonnullOwnPtrVector<KSt
}
auto interpreter_description = TRY(find_elf_interpreter_for_executable(path->view(), *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<FlatPtr> Process::sys$execve(Userspace<Syscall::SC_execve_params const*> user_params)
@@ -903,7 +903,7 @@ ErrorOr<FlatPtr> Process::sys$execve(Userspace<Syscall::SC_execve_params const*>
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<FlatPtr> Process::sys$execve(Userspace<Syscall::SC_execve_params const*>
NonnullOwnPtrVector<KString> 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<FlatPtr> Process::sys$execve(Userspace<Syscall::SC_execve_params const*>
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;
}