summaryrefslogtreecommitdiff
path: root/Kernel/Arch/i386
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-02-21 12:26:12 +0100
committerAndreas Kling <kling@serenityos.org>2020-02-21 15:49:34 +0100
commitd46071c08f19edca854dc7af0e1f0d0887201cb1 (patch)
tree6b4ab1909e6d372dcf97140faf76f800fa144c43 /Kernel/Arch/i386
parent2a679f228e3797f2315c9406193041cd2d4e9e62 (diff)
downloadserenity-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.cpp4
-rw-r--r--Kernel/Arch/i386/CPU.h2
-rw-r--r--Kernel/Arch/i386/PIT.cpp2
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 {