Handle IRQs inside the kernel
All checks were successful
Build documentation / build-and-deploy (push) Successful in 2m42s

This commit is contained in:
2026-03-13 20:33:27 +01:00
parent 4760818118
commit 217179c9a0
84 changed files with 14517 additions and 1297 deletions

View File

@@ -9,7 +9,6 @@
#include <libk/lengthof.h>
#include <libk/std.h>
#include <libk/string.h>
#include <mm/liballoc.h>
#include <proc/reschedule.h>
#include <sys/debug.h>
#include <sys/smp.h>
@@ -114,22 +113,22 @@ static void idt_init (void) {
extern void intr##n (void); \
idt_set (&idt_entries[(n)], (uint64_t)&intr##n, 0x8E, (ist))
/* clang-format off */
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);
IDT_ENTRY (0, 1); IDT_ENTRY (1, 1); IDT_ENTRY (2, 1); IDT_ENTRY (3, 1);
IDT_ENTRY (4, 1); IDT_ENTRY (5, 1); IDT_ENTRY (6, 1); IDT_ENTRY (7, 1);
IDT_ENTRY (8, 1); IDT_ENTRY (9, 1); IDT_ENTRY (10, 1); IDT_ENTRY (11, 1);
IDT_ENTRY (12, 1); IDT_ENTRY (13, 1); IDT_ENTRY (14, 1); IDT_ENTRY (15, 1);
IDT_ENTRY (16, 1); IDT_ENTRY (17, 1); IDT_ENTRY (18, 1); IDT_ENTRY (19, 1);
IDT_ENTRY (20, 1); IDT_ENTRY (21, 1); IDT_ENTRY (22, 1); IDT_ENTRY (23, 1);
IDT_ENTRY (24, 1); IDT_ENTRY (25, 1); IDT_ENTRY (26, 1); IDT_ENTRY (27, 1);
IDT_ENTRY (28, 1); IDT_ENTRY (29, 1); IDT_ENTRY (30, 1); IDT_ENTRY (31, 1);
IDT_ENTRY (32, 2); IDT_ENTRY (33, 2); IDT_ENTRY (34, 2); IDT_ENTRY (35, 2);
IDT_ENTRY (36, 2); IDT_ENTRY (37, 2); IDT_ENTRY (38, 2); IDT_ENTRY (39, 2);
IDT_ENTRY (40, 2); IDT_ENTRY (41, 2); IDT_ENTRY (42, 2); IDT_ENTRY (43, 2);
IDT_ENTRY (44, 2); IDT_ENTRY (45, 2); IDT_ENTRY (46, 2); IDT_ENTRY (47, 2);
IDT_ENTRY (SCHED_PREEMPT_TIMER, 1);
IDT_ENTRY (CPU_REQUEST_SCHED, 1);
IDT_ENTRY (CPU_SPURIOUS, 1);
IDT_ENTRY (SCHED_PREEMPT_TIMER, 2);
IDT_ENTRY (CPU_REQUEST_SCHED, 2);
IDT_ENTRY (CPU_SPURIOUS, 2);
/* clang-format on */
#undef IDT_ENTRY
@@ -141,25 +140,25 @@ static void idt_init (void) {
/* Handle CPU exception and dump registers. If incoming CS has CPL3, kill the process. */
static void intr_exception (struct saved_regs* regs) {
DEBUG ("cpu exception %lu (%lu)\n", regs->trap, regs->error);
DEBUG_NOLOCK ("cpu exception %lu (%lu)\n", regs->trap, regs->error);
uint64_t cr2;
__asm__ volatile ("movq %%cr2, %0" : "=r"(cr2));
uint64_t cr3;
__asm__ volatile ("movq %%cr3, %0" : "=r"(cr3));
debugprintf ("r15=%016lx r14=%016lx r13=%016lx\n"
"r12=%016lx r11=%016lx r10=%016lx\n"
"r9 =%016lx r8 =%016lx rbp=%016lx\n"
"rdi=%016lx rsi=%016lx rdx=%016lx\n"
"rcx=%016lx rax=%016lx trp=%016lx\n"
"err=%016lx rip=%016lx cs =%016lx\n"
"rfl=%016lx rsp=%016lx ss =%016lx\n"
"cr2=%016lx cr3=%016lx rbx=%016lx\n",
regs->r15, regs->r14, regs->r13, regs->r12, regs->r11, regs->r10, regs->r9, regs->r8,
regs->rbp, regs->rdi, regs->rsi, regs->rdx, regs->rcx, regs->rax, regs->trap,
regs->error, regs->rip, regs->cs, regs->rflags, regs->rsp, regs->ss, cr2, cr3,
regs->rbx);
debugprintf_nolock ("r15=%016lx r14=%016lx r13=%016lx\n"
"r12=%016lx r11=%016lx r10=%016lx\n"
"r9 =%016lx r8 =%016lx rbp=%016lx\n"
"rdi=%016lx rsi=%016lx rdx=%016lx\n"
"rcx=%016lx rax=%016lx trp=%016lx\n"
"err=%016lx rip=%016lx cs =%016lx\n"
"rfl=%016lx rsp=%016lx ss =%016lx\n"
"cr2=%016lx cr3=%016lx rbx=%016lx\n",
regs->r15, regs->r14, regs->r13, regs->r12, regs->r11, regs->r10, regs->r9,
regs->r8, regs->rbp, regs->rdi, regs->rsi, regs->rdx, regs->rcx, regs->rax,
regs->trap, regs->error, regs->rip, regs->cs, regs->rflags, regs->rsp,
regs->ss, cr2, cr3, regs->rbx);
if (regs->cs == (GDT_UCODE | 0x03)) {
struct reschedule_ctx rctx;
@@ -177,7 +176,6 @@ static void intr_exception (struct saved_regs* regs) {
if (do_thiscpu)
cpu_request_sched (thiscpu);
} else {
__asm__ volatile ("cli");
spin ();
}
}
@@ -193,21 +191,27 @@ void intr_handler (void* stack_ptr) {
} else {
uint64_t ftc, fpc;
spin_lock (&thiscpu->lock, &ftc);
bool user = false;
struct proc* proc_current = thiscpu->proc_current;
if (regs->cs == (GDT_UCODE | 0x3)) {
user = true;
if (proc_current != NULL) {
spin_lock (&proc_current->lock, &fpc);
memcpy (&proc_current->pdata.regs, regs, sizeof (struct saved_regs));
spin_lock (&thiscpu->lock, &ftc);
fx_save (proc_current->pdata.fx_env);
struct proc* proc_current = thiscpu->proc_current;
spin_unlock (&proc_current->lock, fpc);
if (proc_current != NULL) {
spin_lock (&proc_current->lock, &fpc);
memcpy (&proc_current->pdata.regs, regs, sizeof (struct saved_regs));
fx_save (proc_current->pdata.fx_env);
spin_unlock (&proc_current->lock, fpc);
}
spin_unlock (&thiscpu->lock, ftc);
}
spin_unlock (&thiscpu->lock, ftc);
lapic_eoi ();
struct irq* irq = irq_find (regs->trap);
@@ -217,18 +221,21 @@ void intr_handler (void* stack_ptr) {
struct reschedule_ctx rctx;
memset (&rctx, 0, sizeof (rctx));
irq->func (irq->arg, stack_ptr, &rctx);
bool do_thiscpu = false;
for (size_t i = 0; i < lengthof (rctx.cpus); i++) {
if (rctx.cpus[i] != NULL && rctx.cpus[i] != thiscpu)
cpu_request_sched (rctx.cpus[i]);
else
do_thiscpu = true;
irq->func (irq->arg, stack_ptr, user, &rctx);
if (user) {
bool do_thiscpu = false;
for (size_t i = 0; i < lengthof (rctx.cpus); i++) {
if (rctx.cpus[i] != NULL && rctx.cpus[i] != thiscpu)
cpu_request_sched (rctx.cpus[i]);
else
do_thiscpu = true;
}
if (do_thiscpu)
cpu_request_sched (thiscpu);
}
if (do_thiscpu)
cpu_request_sched (thiscpu);
}
}