1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 21:37:35 +00:00

Kernel: Various stability improvements.

- Don't cli() in Process::do_exec() unless current is execing.
  Eventually this should go away once the scheduler is less retarded
  in the face of interrupts.

- Improved memory access validation for ring0 processes.
  We now look at the kernel ELF header to determine if an access
  is appropriate. :^) It's very hackish but also kinda neat.

- Have Process::die() put the process into a new "Dying" state where
  it can still get scheduled but no signals will be dispatched.
  This way we can keep executing in die() but won't get our EIP
  hijacked by signal dispatch. The main problem here was that die()
  wanted to take various locks.
This commit is contained in:
Andreas Kling 2019-02-06 17:28:14 +01:00
parent 03c0e836f0
commit e05237485c
4 changed files with 41 additions and 14 deletions

View file

@ -67,6 +67,7 @@ public:
Running,
Skip1SchedulerPass,
Skip0SchedulerPasses,
Dying,
Dead,
BeingInspected,
BlockedSleep,
@ -125,7 +126,7 @@ public:
template<typename Callback> static void for_each(Callback);
template<typename Callback> static void for_each_in_pgrp(pid_t, Callback);
template<typename Callback> static void for_each_in_state(State, Callback);
template<typename Callback> static void for_each_not_in_state(State, Callback);
template<typename Callback> static void for_each_living(Callback);
template<typename Callback> void for_each_child(Callback);
bool tick() { ++m_ticks; return --m_ticks_left; }
@ -442,6 +443,7 @@ static inline const char* to_string(Process::State state)
case Process::Invalid: return "Invalid";
case Process::Runnable: return "Runnable";
case Process::Running: return "Running";
case Process::Dying: return "Dying";
case Process::Dead: return "Dead";
case Process::Skip1SchedulerPass: return "Skip1";
case Process::Skip0SchedulerPasses: return "Skip0";
@ -516,12 +518,12 @@ inline void Process::for_each_in_state(State state, Callback callback)
}
template<typename Callback>
inline void Process::for_each_not_in_state(State state, Callback callback)
inline void Process::for_each_living(Callback callback)
{
ASSERT_INTERRUPTS_DISABLED();
for (auto* process = g_processes->head(); process;) {
auto* next_process = process->next();
if (process->state() != state)
if (process->state() != Process::Dead && process->state() != Process::Dying)
callback(*process);
process = next_process;
}