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

Kernel: Assert on page fault during IRQ

We're not equipped to deal with page faults during an IRQ handler,
so add an assertion so we can immediately tell what's wrong.

This is why profiling sometimes hangs the system -- walking the stack
of the profiled thread causes a page fault and things fall apart.
This commit is contained in:
Andreas Kling 2020-02-21 12:26:12 +01:00
parent 2a679f228e
commit d46071c08f
4 changed files with 9 additions and 0 deletions

View file

@ -545,14 +545,18 @@ void load_task_register(u16 selector)
asm("ltr %0" ::"r"(selector)); asm("ltr %0" ::"r"(selector));
} }
u32 g_in_irq;
void handle_irq(RegisterState regs) void handle_irq(RegisterState regs)
{ {
clac(); clac();
++g_in_irq;
ASSERT(regs.isr_number >= 0x50 && regs.isr_number <= 0x5f); ASSERT(regs.isr_number >= 0x50 && regs.isr_number <= 0x5f);
u8 irq = (u8)(regs.isr_number - 0x50); u8 irq = (u8)(regs.isr_number - 0x50);
if (s_irq_handler[irq]) if (s_irq_handler[irq])
s_irq_handler[irq]->handle_irq(); s_irq_handler[irq]->handle_irq();
PIC::eoi(irq); PIC::eoi(irq);
--g_in_irq;
} }
void sse_init() void sse_init()

View file

@ -592,4 +592,6 @@ private:
u32 m_flags; u32 m_flags;
}; };
extern u32 g_in_irq;
} }

View file

@ -67,6 +67,7 @@ static u32 s_seconds_since_boot;
void timer_interrupt_handler(RegisterState regs) void timer_interrupt_handler(RegisterState regs)
{ {
clac(); clac();
++g_in_irq;
IRQHandlerScope scope(IRQ_TIMER); IRQHandlerScope scope(IRQ_TIMER);
if (++s_ticks_this_second >= TICKS_PER_SECOND) { if (++s_ticks_this_second >= TICKS_PER_SECOND) {
// FIXME: Synchronize with the RTC somehow to prevent drifting apart. // FIXME: Synchronize with the RTC somehow to prevent drifting apart.
@ -74,6 +75,7 @@ void timer_interrupt_handler(RegisterState regs)
s_ticks_this_second = 0; s_ticks_this_second = 0;
} }
Scheduler::timer_tick(regs); Scheduler::timer_tick(regs);
--g_in_irq;
} }
namespace PIT { namespace PIT {

View file

@ -281,6 +281,7 @@ PageFaultResponse MemoryManager::handle_page_fault(const PageFault& fault)
{ {
ASSERT_INTERRUPTS_DISABLED(); ASSERT_INTERRUPTS_DISABLED();
ASSERT(Thread::current); ASSERT(Thread::current);
ASSERT(!g_in_irq);
#ifdef PAGE_FAULT_DEBUG #ifdef PAGE_FAULT_DEBUG
dbgprintf("MM: handle_page_fault(%w) at V%p\n", fault.code(), fault.vaddr().get()); dbgprintf("MM: handle_page_fault(%w) at V%p\n", fault.code(), fault.vaddr().get());
#endif #endif