1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-30 21:48:11 +00:00

Kernel: Track previous mode when entering/exiting traps

This allows us to determine what the previous mode (user or kernel)
was, e.g. in the timer interrupt. This is used e.g. to determine
whether a signal handler should be set up.

Fixes #5096
This commit is contained in:
Tom 2021-01-25 13:19:34 -07:00 committed by Andreas Kling
parent fa18010477
commit 0bd558081e
6 changed files with 70 additions and 7 deletions

View file

@ -699,6 +699,8 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal)
return DispatchSignalResult::Deferred;
}
ASSERT(previous_mode() == PreviousMode::UserMode);
auto& action = m_signal_action_data[signal];
// FIXME: Implement SA_SIGINFO signal handlers.
ASSERT(!(action.flags & SA_SIGINFO));
@ -762,6 +764,9 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal)
return DispatchSignalResult::Continue;
}
ASSERT(previous_mode() == PreviousMode::UserMode);
ASSERT(current_trap());
ProcessPagingScope paging_scope(m_process);
u32 old_signal_mask = m_signal_mask;
@ -843,7 +848,19 @@ bool Thread::push_value_on_stack(FlatPtr value)
RegisterState& Thread::get_register_dump_from_stack()
{
return *(RegisterState*)(kernel_stack_top() - sizeof(RegisterState));
auto* trap = current_trap();
// We should *always* have a trap. If we don't we're probably a kernel
// thread that hasn't been pre-empted. If we want to support this, we
// need to capture the registers probably into m_tss and return it
ASSERT(trap);
while (trap) {
if (!trap->next_trap)
break;
trap = trap->next_trap;
}
return *trap->regs;
}
RefPtr<Thread> Thread::clone(Process& process)