Kernel/x86: Add an APIC-specific spurious interrupt handler

The old SpuriousInterruptHandler only works with PICs.
It assumes that it always has a parent IRQController, which isn't the
case for APICs (APICs aren't represented by an IRQController).
This didn't cause a crash because get_responsible_irq_controller()'s
logic of determining the correct IRQController is broken at the moment
and always returns the first I/O APIC. This bug will be fixed by a
future commit.

Additionally, SpuriousInterruptHandler always tries to use
IRQController::get_isr() in its handle_interrupt() function, which
only the PIC class implements.
This commit is contained in:
Sönke Holz authored and Sönke Holz committed 2026-07-12 13:14:12 +02:00
1 parent 920062e64e
commit d2eb593961
1 file changed
+38 -2
+38 -2
View File
@@ -16,7 +16,6 @@
#include <Kernel/Debug.h>
#include <Kernel/Firmware/ACPI/Parser.h>
#include <Kernel/Firmware/ACPI/StaticParsing.h>
#include <Kernel/Interrupts/SpuriousInterruptHandler.h>
#include <Kernel/Library/Panic.h>
#include <Kernel/Memory/AnonymousVMObject.h>
#include <Kernel/Memory/MemoryManager.h>
@@ -119,6 +118,31 @@ public:
private:
};
class APICSpuriousInterruptHandler final : public GenericInterruptHandler {
public:
explicit APICSpuriousInterruptHandler(InterruptNumber interrupt_vector)
: GenericInterruptHandler(interrupt_vector, true)
{
}
static void initialize(InterruptNumber interrupt_number)
{
auto* handler = new APICSpuriousInterruptHandler(interrupt_number);
handler->register_interrupt_handler();
}
virtual bool handle_interrupt() override;
virtual bool eoi() override;
virtual HandlerType type() const override { return HandlerType::IRQHandler; }
virtual StringView purpose() const override { return "APIC Spurious Interrupt Handler"sv; }
virtual StringView controller() const override { return {}; }
virtual size_t sharing_devices_count() const override { return 0; }
virtual bool is_shared_handler() const override { return false; }
};
bool APIC::initialized()
{
return s_apic.is_initialized();
@@ -485,7 +509,7 @@ UNMAP_AFTER_INIT void APIC::enable(u32 cpu)
dbgln_if(APIC_DEBUG, "Enabling local APIC for CPU #{}, logical APIC ID: {}", cpu, apic_id);
if (cpu == 0) {
SpuriousInterruptHandler::initialize(IRQ_APIC_SPURIOUS);
APICSpuriousInterruptHandler::initialize(IRQ_APIC_SPURIOUS);
APICErrInterruptHandler::initialize(IRQ_APIC_ERR);
@@ -668,6 +692,18 @@ bool APICErrInterruptHandler::eoi()
return true;
}
bool APICSpuriousInterruptHandler::handle_interrupt()
{
dbgln("APIC: Spurious interrupt");
return true;
}
bool APICSpuriousInterruptHandler::eoi()
{
APIC::the().eoi();
return true;
}
bool HardwareTimer<GenericInterruptHandler>::eoi()
{
APIC::the().eoi();