From 8c6c63465f44552c5480af54f5c25a2c4c5131c6 Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Mon, 30 Mar 2026 11:43:09 +0200 Subject: [PATCH] Use dedicated NMI stack on i686 --- sdk/xtdk/i686/ketypes.h | 2 +- xtoskrnl/ar/i686/data.cc | 3 +++ xtoskrnl/ar/i686/procsup.cc | 27 +++++++++++++++++---------- xtoskrnl/includes/ar/i686/procsup.hh | 9 ++++++--- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/sdk/xtdk/i686/ketypes.h b/sdk/xtdk/i686/ketypes.h index 86fa1ff..e2efaaa 100644 --- a/sdk/xtdk/i686/ketypes.h +++ b/sdk/xtdk/i686/ketypes.h @@ -130,7 +130,7 @@ /* XTOS Kernel stack size */ #define KERNEL_STACK_SIZE 0x4000 -#define KERNEL_STACKS 2 +#define KERNEL_STACKS 3 /* XTOS Kernel stack guard pages */ #define KERNEL_STACK_GUARD_PAGES 1 diff --git a/xtoskrnl/ar/i686/data.cc b/xtoskrnl/ar/i686/data.cc index fab40cc..c8599e4 100644 --- a/xtoskrnl/ar/i686/data.cc +++ b/xtoskrnl/ar/i686/data.cc @@ -30,5 +30,8 @@ KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock; /* Initial TSS */ KTSS AR::ProcSup::InitialTss; +/* Initial kernel NMI stack */ +UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {}; + /* NMI task gate */ UCHAR AR::ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS]; diff --git a/xtoskrnl/ar/i686/procsup.cc b/xtoskrnl/ar/i686/procsup.cc index 8709598..cdbc680 100644 --- a/xtoskrnl/ar/i686/procsup.cc +++ b/xtoskrnl/ar/i686/procsup.cc @@ -132,7 +132,7 @@ VOID AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures) { KDESCRIPTOR GdtDescriptor, IdtDescriptor; - PVOID KernelBootStack, KernelFaultStack; + PVOID KernelBootStack, KernelFaultStack, KernelNmiStack; PKPROCESSOR_BLOCK ProcessorBlock; PKGDTENTRY Gdt; PKIDTENTRY Idt; @@ -143,7 +143,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures) { /* Assign CPU structures from provided buffer */ InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock, - &KernelBootStack, &KernelFaultStack); + &KernelBootStack, &KernelFaultStack, &KernelNmiStack); /* Use global IDT */ Idt = InitialIdt; @@ -156,6 +156,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures) Tss = &InitialTss; KernelBootStack = &BootStack; KernelFaultStack = &FaultStack; + KernelNmiStack = &NmiStack; ProcessorBlock = &InitialProcessorBlock; } @@ -165,7 +166,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures) /* Initialize GDT, IDT and TSS */ InitializeGdt(ProcessorBlock); InitializeIdt(ProcessorBlock); - InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack); + InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack); /* Set GDT and IDT descriptors */ GdtDescriptor.Base = Gdt; @@ -381,7 +382,8 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures, OUT PKTSS *Tss, OUT PKPROCESSOR_BLOCK *ProcessorBlock, OUT PVOID *KernelBootStack, - OUT PVOID *KernelFaultStack) + OUT PVOID *KernelFaultStack, + OUT PVOID *KernelNmiStack) { UINT_PTR Address; @@ -392,8 +394,12 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures, *KernelBootStack = (PVOID)Address; 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; + 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 */ *Gdt = (PKGDTENTRY)(PVOID)Address; @@ -439,7 +445,8 @@ XTAPI VOID AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, IN PVOID KernelBootStack, - IN PVOID KernelFaultStack) + IN PVOID KernelFaultStack, + IN PVOID KernelNmiStack) { /* Clear I/O map */ RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE); @@ -471,7 +478,7 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, /* Initialize task gates for DoubleFault and NMI traps */ SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack); - SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack); + SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelNmiStack); } /** @@ -701,7 +708,7 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt, XTAPI VOID AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelFaultStack) + IN PVOID KernelNmiStack) { PKGDTENTRY TaskGateEntry, TssEntry; PKTSS Tss; @@ -719,8 +726,8 @@ AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock Tss->Flags = 0; Tss->LDT = KGDT_R0_LDT; Tss->CR3 = CpuFunc::ReadControlRegister(3); - Tss->Esp = (ULONG_PTR)KernelFaultStack; - Tss->Esp0 = (ULONG_PTR)KernelFaultStack; + Tss->Esp = (ULONG_PTR)KernelNmiStack; + Tss->Esp0 = (ULONG_PTR)KernelNmiStack; Tss->Eip = PtrToUlong(ArTrapEntry[0x02]); Tss->Cs = KGDT_R0_CODE; Tss->Ds = KGDT_R3_DATA | RPL_MASK; diff --git a/xtoskrnl/includes/ar/i686/procsup.hh b/xtoskrnl/includes/ar/i686/procsup.hh index 2b4931f..fd1c6fc 100644 --- a/xtoskrnl/includes/ar/i686/procsup.hh +++ b/xtoskrnl/includes/ar/i686/procsup.hh @@ -25,6 +25,7 @@ namespace AR STATIC KIDTENTRY InitialIdt[IDT_ENTRIES]; STATIC KPROCESSOR_BLOCK InitialProcessorBlock; STATIC KTSS InitialTss; + STATIC UCHAR NmiStack[KERNEL_STACK_SIZE]; STATIC UCHAR NonMaskableInterruptTss[KTSS_IO_MAPS]; @@ -57,11 +58,13 @@ namespace AR OUT PKTSS *Tss, OUT PKPROCESSOR_BLOCK *ProcessorBlock, OUT PVOID *KernelBootStack, - OUT PVOID *KernelFaultStack); + OUT PVOID *KernelFaultStack, + OUT PVOID *KernelNmiStack); STATIC XTAPI VOID InitializeSegments(VOID); STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, IN PVOID KernelBootStack, - IN PVOID KernelFaultStack); + IN PVOID KernelFaultStack, + IN PVOID KernelNmiStack); STATIC XTAPI VOID SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, IN PVOID KernelFaultStack); STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt, @@ -75,7 +78,7 @@ namespace AR IN USHORT Selector, IN ULONG_PTR Base); STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelFaultStack); + IN PVOID KernelNmiStack); }; }