diff --git a/Kernel/Arch/i386/CPU.h b/Kernel/Arch/i386/CPU.h index 39168b3be7..c5883caa51 100644 --- a/Kernel/Arch/i386/CPU.h +++ b/Kernel/Arch/i386/CPU.h @@ -44,6 +44,12 @@ class PageDirectory; class PageTableEntry; static constexpr u32 safe_eflags_mask = 0xdff; +static constexpr u32 iopl_mask = 3u << 12; + +inline u32 get_iopl_from_eflags(u32 eflags) +{ + return (eflags & iopl_mask) >> 12; +} struct [[gnu::packed]] DescriptorTablePointer { diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 7283630f97..e5b0aa8adc 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -356,6 +356,14 @@ bool Scheduler::context_switch(Thread* thread) enter_current(*from_thread, false); ASSERT(thread == Thread::current()); +#if ARCH(I386) + auto iopl = get_iopl_from_eflags(Thread::current()->get_register_dump_from_stack().eflags); + if (thread->process().is_user_process() && iopl != 0) { + dbgln("PANIC: Switched to thread {} with non-zero IOPL={}", Thread::current()->tid().value(), iopl); + Processor::halt(); + } +#endif + return true; }