Implement NMI stack handling via IST
All checks were successful
Builds / ExectOS (amd64, release) (push) Successful in 40s
Builds / ExectOS (amd64, debug) (push) Successful in 33s
Builds / ExectOS (i686, release) (push) Successful in 30s
Builds / ExectOS (i686, debug) (push) Successful in 39s

This commit is contained in:
2026-03-28 20:49:18 +01:00
parent 3ce009db41
commit a608b26fde
4 changed files with 26 additions and 10 deletions

View File

@@ -58,6 +58,7 @@
#define KIDT_IST_RESERVED 0 #define KIDT_IST_RESERVED 0
#define KIDT_IST_PANIC 1 #define KIDT_IST_PANIC 1
#define KIDT_IST_MCA 2 #define KIDT_IST_MCA 2
#define KIDT_IST_NMI 3
/* AMD64 Segment Types */ /* AMD64 Segment Types */
#define AMD64_TASK_GATE 0x5 #define AMD64_TASK_GATE 0x5

View File

@@ -26,3 +26,6 @@ KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
/* Initial TSS */ /* Initial TSS */
KTSS AR::ProcSup::InitialTss; KTSS AR::ProcSup::InitialTss;
/* Initial kernel NMI stack */
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};

View File

@@ -136,8 +136,8 @@ XTAPI
VOID VOID
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures) AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
{ {
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
KDESCRIPTOR GdtDescriptor, IdtDescriptor; KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PVOID KernelBootStack, KernelFaultStack;
PKPROCESSOR_BLOCK ProcessorBlock; PKPROCESSOR_BLOCK ProcessorBlock;
PKGDTENTRY Gdt; PKGDTENTRY Gdt;
PKIDTENTRY Idt; PKIDTENTRY Idt;
@@ -148,7 +148,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
{ {
/* Assign CPU structures from provided buffer */ /* Assign CPU structures from provided buffer */
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock, InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
&KernelBootStack, &KernelFaultStack); &KernelBootStack, &KernelFaultStack, &KernelNmiStack);
/* Use global IDT */ /* Use global IDT */
Idt = InitialIdt; Idt = InitialIdt;
@@ -161,6 +161,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
Tss = &InitialTss; Tss = &InitialTss;
KernelBootStack = &BootStack; KernelBootStack = &BootStack;
KernelFaultStack = &FaultStack; KernelFaultStack = &FaultStack;
KernelNmiStack = &NmiStack;
ProcessorBlock = &InitialProcessorBlock; ProcessorBlock = &InitialProcessorBlock;
} }
@@ -170,7 +171,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
/* Initialize GDT, IDT and TSS */ /* Initialize GDT, IDT and TSS */
InitializeGdt(ProcessorBlock); InitializeGdt(ProcessorBlock);
InitializeIdt(ProcessorBlock); InitializeIdt(ProcessorBlock);
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack); InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);
/* Set GDT and IDT descriptors */ /* Set GDT and IDT descriptors */
GdtDescriptor.Base = Gdt; GdtDescriptor.Base = Gdt;
@@ -256,7 +257,7 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
/* Setup IDT handlers for known interrupts and traps */ /* Setup IDT handlers for known interrupts and traps */
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, KIDT_IST_NMI, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
@@ -277,7 +278,7 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrapEntry[0x2F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrapEntry[0x2F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrapEntry[0xE1], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArInterruptEntry[0xE1], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
} }
/** /**
@@ -429,7 +430,8 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKTSS *Tss, OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock, OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack, OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack) OUT PVOID *KernelFaultStack,
OUT PVOID *KernelNmiStack)
{ {
UINT_PTR Address; UINT_PTR Address;
@@ -440,8 +442,12 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
*KernelBootStack = (PVOID)Address; *KernelBootStack = (PVOID)Address;
Address += KERNEL_STACK_SIZE; Address += KERNEL_STACK_SIZE;
/* Assign a space for kernel fault stack, no advance needed as stack grows down */ /* Assign a space for kernel fault stack and advance */
*KernelFaultStack = (PVOID)Address; *KernelFaultStack = (PVOID)Address;
Address += KERNEL_STACK_SIZE;
/* Assign a space for kernel NMI stack, no advance needed as stack grows down */
*KernelNmiStack = (PVOID)Address;
/* Assign a space for GDT and advance */ /* Assign a space for GDT and advance */
*Gdt = (PKGDTENTRY)(PVOID)Address; *Gdt = (PKGDTENTRY)(PVOID)Address;
@@ -492,7 +498,8 @@ XTAPI
VOID VOID
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack, IN PVOID KernelBootStack,
IN PVOID KernelFaultStack) IN PVOID KernelFaultStack,
IN PVOID KernelNmiStack)
{ {
/* Fill TSS with zeroes */ /* Fill TSS with zeroes */
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS)); RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
@@ -502,6 +509,8 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)KernelBootStack; ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)KernelBootStack;
ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)KernelFaultStack; ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)KernelFaultStack;
ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)KernelFaultStack; ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)KernelFaultStack;
ProcessorBlock->TssBase->Ist[KIDT_IST_NMI] = (ULONG_PTR)KernelNmiStack;
} }
/** /**

View File

@@ -24,6 +24,7 @@ namespace AR
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES]; STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
STATIC KPROCESSOR_BLOCK InitialProcessorBlock; STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
STATIC KTSS InitialTss; STATIC KTSS InitialTss;
STATIC UCHAR NmiStack[KERNEL_STACK_SIZE];
public: public:
STATIC XTAPI PVOID GetBootStack(VOID); STATIC XTAPI PVOID GetBootStack(VOID);
@@ -54,11 +55,13 @@ namespace AR
OUT PKTSS *Tss, OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock, OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack, OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack); OUT PVOID *KernelFaultStack,
OUT PVOID *KernelNmiStack);
STATIC XTAPI VOID InitializeSegments(VOID); STATIC XTAPI VOID InitializeSegments(VOID);
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack, IN PVOID KernelBootStack,
IN PVOID KernelFaultStack); IN PVOID KernelFaultStack,
IN PVOID KernelNmiStack);
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt, STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base, IN ULONG_PTR Base,