From 259aa732c8bac50ce133a3cbba88dbf7d5f19701 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Mon, 22 Dec 2025 22:19:01 +0100 Subject: [PATCH] Use separate IST stack for IRQs and cpu exceptions --- kernel/amd64/bootmain.c | 2 + kernel/amd64/init.c | 6 ++- kernel/amd64/intr.c | 102 ++++++++++++++++++++-------------------- 3 files changed, 57 insertions(+), 53 deletions(-) diff --git a/kernel/amd64/bootmain.c b/kernel/amd64/bootmain.c index 4d0f706..c8d8765 100644 --- a/kernel/amd64/bootmain.c +++ b/kernel/amd64/bootmain.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,7 @@ ALIGNED (16) static uint8_t uacpi_memory_buffer[UACPI_MEMORY_BUFFER_MAX]; void bootmain (void) { amd64_init (); + amd64_debug_init (); pmm_init (); mm_init (); diff --git a/kernel/amd64/init.c b/kernel/amd64/init.c index 2016fc0..16327bd 100644 --- a/kernel/amd64/init.c +++ b/kernel/amd64/init.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -38,6 +37,8 @@ struct gdt_extended { } PACKED; ALIGNED (16) static volatile uint8_t kernel_stack[KSTACK_SIZE]; +ALIGNED (16) static volatile uint8_t except_stack[KSTACK_SIZE]; +ALIGNED (16) static volatile uint8_t irq_stack[KSTACK_SIZE]; ALIGNED (16) static volatile struct gdt_extended gdt; static void amd64_gdt_set (volatile struct gdt_entry* ent, uint32_t base, uint32_t limit, @@ -59,6 +60,8 @@ static void amd64_gdt_init (void) { tss->iopb_off = sizeof (*tss); tss->rsp0 = (uint64_t)((uintptr_t)kernel_stack + sizeof (kernel_stack)); + tss->ist[0] = (uint64_t)((uintptr_t)except_stack + sizeof (except_stack)); + tss->ist[1] = (uint64_t)((uintptr_t)irq_stack + sizeof (irq_stack)); uint64_t tssbase = (uint64_t)&tss; uint64_t tsslimit = sizeof (*tss) - 1; @@ -101,6 +104,5 @@ static void amd64_gdt_init (void) { void amd64_init (void) { amd64_gdt_init (); - amd64_debug_init (); amd64_intr_init (); } diff --git a/kernel/amd64/intr.c b/kernel/amd64/intr.c index 62df754..8856f1c 100644 --- a/kernel/amd64/intr.c +++ b/kernel/amd64/intr.c @@ -77,7 +77,7 @@ static void amd64_init_pic (void) { #undef IO_OP } -static void amd64_idt_set (volatile struct idt_entry* ent, uint64_t handler, uint8_t flags) { +static void amd64_idt_set (volatile struct idt_entry* ent, uint64_t handler, uint8_t flags, uint8_t ist) { ent->intrlow = (handler & 0xFFFF); ent->kernel_cs = 0x08; // GDT_KCODE (init.c) ent->ist = 0; @@ -90,57 +90,57 @@ static void amd64_idt_set (volatile struct idt_entry* ent, uint64_t handler, uin static void amd64_idt_init (void) { memset ((void*)idt_entries, 0, sizeof (idt_entries)); -#define IDT_ENTRY(n) \ +#define IDT_ENTRY(n, ist) \ extern void amd64_intr##n (void); \ - amd64_idt_set (&idt_entries[(n)], (uint64_t)&amd64_intr##n, 0x8E) - IDT_ENTRY (0); - IDT_ENTRY (1); - IDT_ENTRY (2); - IDT_ENTRY (3); - IDT_ENTRY (4); - IDT_ENTRY (5); - IDT_ENTRY (6); - IDT_ENTRY (7); - IDT_ENTRY (8); - IDT_ENTRY (9); - IDT_ENTRY (10); - IDT_ENTRY (11); - IDT_ENTRY (12); - IDT_ENTRY (13); - IDT_ENTRY (14); - IDT_ENTRY (15); - IDT_ENTRY (16); - IDT_ENTRY (17); - IDT_ENTRY (18); - IDT_ENTRY (19); - IDT_ENTRY (20); - IDT_ENTRY (21); - IDT_ENTRY (22); - IDT_ENTRY (23); - IDT_ENTRY (24); - IDT_ENTRY (25); - IDT_ENTRY (26); - IDT_ENTRY (27); - IDT_ENTRY (28); - IDT_ENTRY (29); - IDT_ENTRY (30); - IDT_ENTRY (31); - IDT_ENTRY (32); - IDT_ENTRY (33); - IDT_ENTRY (34); - IDT_ENTRY (35); - IDT_ENTRY (36); - IDT_ENTRY (37); - IDT_ENTRY (38); - IDT_ENTRY (39); - IDT_ENTRY (40); - IDT_ENTRY (41); - IDT_ENTRY (42); - IDT_ENTRY (43); - IDT_ENTRY (44); - IDT_ENTRY (45); - IDT_ENTRY (46); - IDT_ENTRY (47); + amd64_idt_set (&idt_entries[(n)], (uint64_t)&amd64_intr##n, 0x8E, (ist)) + IDT_ENTRY (0, 0); + IDT_ENTRY (1, 0); + IDT_ENTRY (2, 0); + IDT_ENTRY (3, 0); + IDT_ENTRY (4, 0); + IDT_ENTRY (5, 0); + IDT_ENTRY (6, 0); + IDT_ENTRY (7, 0); + IDT_ENTRY (8, 0); + IDT_ENTRY (9, 0); + IDT_ENTRY (10, 0); + IDT_ENTRY (11, 0); + IDT_ENTRY (12, 0); + IDT_ENTRY (13, 0); + IDT_ENTRY (14, 0); + IDT_ENTRY (15, 0); + IDT_ENTRY (16, 0); + IDT_ENTRY (17, 0); + IDT_ENTRY (18, 0); + IDT_ENTRY (19, 0); + IDT_ENTRY (20, 0); + IDT_ENTRY (21, 0); + IDT_ENTRY (22, 0); + IDT_ENTRY (23, 0); + IDT_ENTRY (24, 0); + IDT_ENTRY (25, 0); + IDT_ENTRY (26, 0); + IDT_ENTRY (27, 0); + IDT_ENTRY (28, 0); + IDT_ENTRY (29, 0); + IDT_ENTRY (30, 0); + IDT_ENTRY (31, 0); + IDT_ENTRY (32, 1); + IDT_ENTRY (33, 1); + IDT_ENTRY (34, 1); + IDT_ENTRY (35, 1); + IDT_ENTRY (36, 1); + IDT_ENTRY (37, 1); + IDT_ENTRY (38, 1); + IDT_ENTRY (39, 1); + IDT_ENTRY (40, 1); + IDT_ENTRY (41, 1); + IDT_ENTRY (42, 1); + IDT_ENTRY (43, 1); + IDT_ENTRY (44, 1); + IDT_ENTRY (45, 1); + IDT_ENTRY (46, 1); + IDT_ENTRY (47, 1); #undef IDT_ENTRY idt.limit = sizeof (idt_entries) - 1;