diff options
author | Andreas Kling <kling@serenityos.org> | 2020-02-21 12:26:12 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-02-21 15:49:34 +0100 |
commit | d46071c08f19edca854dc7af0e1f0d0887201cb1 (patch) | |
tree | 6b4ab1909e6d372dcf97140faf76f800fa144c43 /Kernel/Arch/i386 | |
parent | 2a679f228e3797f2315c9406193041cd2d4e9e62 (diff) | |
download | serenity-d46071c08f19edca854dc7af0e1f0d0887201cb1.zip |
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.
Diffstat (limited to 'Kernel/Arch/i386')
-rw-r--r-- | Kernel/Arch/i386/CPU.cpp | 4 | ||||
-rw-r--r-- | Kernel/Arch/i386/CPU.h | 2 | ||||
-rw-r--r-- | Kernel/Arch/i386/PIT.cpp | 2 |
3 files changed, 8 insertions, 0 deletions
diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp index 722f0fd356..afd7b5ecd2 100644 --- a/Kernel/Arch/i386/CPU.cpp +++ b/Kernel/Arch/i386/CPU.cpp @@ -545,14 +545,18 @@ void load_task_register(u16 selector) asm("ltr %0" ::"r"(selector)); } +u32 g_in_irq; + void handle_irq(RegisterState regs) { clac(); + ++g_in_irq; ASSERT(regs.isr_number >= 0x50 && regs.isr_number <= 0x5f); u8 irq = (u8)(regs.isr_number - 0x50); if (s_irq_handler[irq]) s_irq_handler[irq]->handle_irq(); PIC::eoi(irq); + --g_in_irq; } void sse_init() diff --git a/Kernel/Arch/i386/CPU.h b/Kernel/Arch/i386/CPU.h index 25937ffef2..0bc0cc1d1d 100644 --- a/Kernel/Arch/i386/CPU.h +++ b/Kernel/Arch/i386/CPU.h @@ -592,4 +592,6 @@ private: u32 m_flags; }; +extern u32 g_in_irq; + } diff --git a/Kernel/Arch/i386/PIT.cpp b/Kernel/Arch/i386/PIT.cpp index fac215a126..c74576747b 100644 --- a/Kernel/Arch/i386/PIT.cpp +++ b/Kernel/Arch/i386/PIT.cpp @@ -67,6 +67,7 @@ static u32 s_seconds_since_boot; void timer_interrupt_handler(RegisterState regs) { clac(); + ++g_in_irq; IRQHandlerScope scope(IRQ_TIMER); if (++s_ticks_this_second >= TICKS_PER_SECOND) { // 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; } Scheduler::timer_tick(regs); + --g_in_irq; } namespace PIT { |