From 9479f3d3641d67ac7bef38879135933e63ae78b4 Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Wed, 25 Mar 2026 22:52:58 +0100 Subject: [PATCH 1/2] Implement APIC presence check and panic if unsupported --- xtoskrnl/hl/x86/pic.cc | 43 +++++++++++++++++++++++++++++++++++++ xtoskrnl/includes/hl/pic.hh | 1 + 2 files changed, 44 insertions(+) diff --git a/xtoskrnl/hl/x86/pic.cc b/xtoskrnl/hl/x86/pic.cc index 2d31e2b..8fefc6c 100644 --- a/xtoskrnl/hl/x86/pic.cc +++ b/xtoskrnl/hl/x86/pic.cc @@ -9,6 +9,41 @@ #include +/** + * Checks whether the APIC is supported by the processor. + * + * @return This routine returns TRUE if APIC is supported, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +HL::Pic::CheckApicSupport(VOID) +{ + CPUID_REGISTERS CpuRegisters; + + /* Prepare CPUID registers */ + CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; + CpuRegisters.SubLeaf = 0; + CpuRegisters.Eax = 0; + CpuRegisters.Ebx = 0; + CpuRegisters.Ecx = 0; + CpuRegisters.Edx = 0; + + /* Get CPUID */ + AR::CpuFunc::CpuId(&CpuRegisters); + + /* Check APIC status from the CPUID results */ + if(!(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC)) + { + /* APIC is not supported */ + return FALSE; + } + + /* APIC is supported */ + return TRUE; +} + /** * Checks whether the x2APIC extension is supported by the processor. * @@ -124,6 +159,14 @@ HL::Pic::InitializeApic(VOID) APIC_LVT_REGISTER LvtRegister; ULONG CpuNumber; + /* Check APIC support */ + if(!CheckApicSupport()) + { + /* APIC is not supported, raise kernel panic */ + DebugPrint(L"FATAL ERROR: Local APIC not present.\n"); + KE::Crash::Panic(0x5D, CPUID_GET_STANDARD1_FEATURES, 0x0, 0x0, CPUID_FEATURES_EDX_APIC); + } + /* Determine APIC mode (xAPIC compatibility or x2APIC) */ if(CheckX2ApicSupport()) { diff --git a/xtoskrnl/includes/hl/pic.hh b/xtoskrnl/includes/hl/pic.hh index 85b8fca..c90b098 100644 --- a/xtoskrnl/includes/hl/pic.hh +++ b/xtoskrnl/includes/hl/pic.hh @@ -32,6 +32,7 @@ namespace HL IN ULONGLONG Value); private: + STATIC XTAPI BOOLEAN CheckApicSupport(VOID); STATIC XTAPI BOOLEAN CheckX2ApicSupport(VOID); STATIC XTCDECL VOID HandleApicSpuriousService(VOID); STATIC XTCDECL VOID HandlePicSpuriousService(VOID); From 9b19bc94b3a2d74134458f718f7bc2522d2fa1ce Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Thu, 26 Mar 2026 23:10:00 +0100 Subject: [PATCH 2/2] Replace manual IDT manipulation with SetIdtGate function call --- xtoskrnl/includes/ar/amd64/procsup.hh | 14 +++++++------- xtoskrnl/includes/ar/i686/procsup.hh | 14 +++++++------- xtoskrnl/ke/amd64/irq.cc | 10 +++++++--- xtoskrnl/ke/i686/irq.cc | 9 +++++++-- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/xtoskrnl/includes/ar/amd64/procsup.hh b/xtoskrnl/includes/ar/amd64/procsup.hh index 949e8c2..4cad247 100644 --- a/xtoskrnl/includes/ar/amd64/procsup.hh +++ b/xtoskrnl/includes/ar/amd64/procsup.hh @@ -31,6 +31,13 @@ namespace AR OUT PVOID *TrampolineCode, OUT PULONG_PTR TrampolineSize); STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures); + STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt, + IN USHORT Vector, + IN PVOID Handler, + IN USHORT Selector, + IN USHORT Ist, + IN USHORT Dpl, + IN USHORT Type); private: STATIC XTAPI VOID IdentifyProcessor(VOID); @@ -62,13 +69,6 @@ namespace AR STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt, IN USHORT Selector, IN ULONG_PTR Base); - STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt, - IN USHORT Vector, - IN PVOID Handler, - IN USHORT Selector, - IN USHORT Ist, - IN USHORT Dpl, - IN USHORT Type); }; } diff --git a/xtoskrnl/includes/ar/i686/procsup.hh b/xtoskrnl/includes/ar/i686/procsup.hh index 14122cb..2b4931f 100644 --- a/xtoskrnl/includes/ar/i686/procsup.hh +++ b/xtoskrnl/includes/ar/i686/procsup.hh @@ -34,6 +34,13 @@ namespace AR OUT PVOID *TrampolineCode, OUT PULONG_PTR TrampolineSize); STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures); + STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt, + IN USHORT Vector, + IN PVOID Handler, + IN USHORT Selector, + IN USHORT Ist, + IN USHORT Dpl, + IN USHORT Type); private: STATIC XTAPI VOID IdentifyProcessor(VOID); @@ -67,13 +74,6 @@ namespace AR STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt, IN USHORT Selector, IN ULONG_PTR Base); - STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt, - IN USHORT Vector, - IN PVOID Handler, - IN USHORT Selector, - IN USHORT Ist, - IN USHORT Dpl, - IN USHORT Type); STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, IN PVOID KernelFaultStack); diff --git a/xtoskrnl/ke/amd64/irq.cc b/xtoskrnl/ke/amd64/irq.cc index 0d39623..209cd7c 100644 --- a/xtoskrnl/ke/amd64/irq.cc +++ b/xtoskrnl/ke/amd64/irq.cc @@ -33,7 +33,11 @@ KE::Irq::SetInterruptHandler(IN ULONG Vector, ProcessorBlock = KE::Processor::GetCurrentProcessorBlock(); /* Update interrupt handler */ - ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF); - ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF); - ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetHigh = (ULONG_PTR)Handler >> 32; + AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase, + Vector, + Handler, + KGDT_R0_CODE, + 0, + KIDT_ACCESS_RING0, + AMD64_INTERRUPT_GATE); } diff --git a/xtoskrnl/ke/i686/irq.cc b/xtoskrnl/ke/i686/irq.cc index 556d006..9e33c7c 100644 --- a/xtoskrnl/ke/i686/irq.cc +++ b/xtoskrnl/ke/i686/irq.cc @@ -33,6 +33,11 @@ KE::Irq::SetInterruptHandler(IN ULONG Vector, ProcessorBlock = KE::Processor::GetCurrentProcessorBlock(); /* Update interrupt handler */ - ProcessorBlock->IdtBase[(UCHAR) Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF); - ProcessorBlock->IdtBase[(UCHAR) Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16); + AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase, + Vector, + Handler, + KGDT_R0_CODE, + 0, + KIDT_ACCESS_RING0, + I686_INTERRUPT_GATE); }