diff --git a/kernel/include/interrupts/Interrupts.h b/kernel/include/interrupts/Interrupts.h index 883a8527..c87edbf0 100644 --- a/kernel/include/interrupts/Interrupts.h +++ b/kernel/include/interrupts/Interrupts.h @@ -7,6 +7,5 @@ namespace Interrupts void disable(); bool is_in_handler(); - void ensure_handler(); void return_from_handler(Context* context); } \ No newline at end of file diff --git a/kernel/include/trace/StackTracer.h b/kernel/include/trace/StackTracer.h index 83355ef8..b82234f2 100644 --- a/kernel/include/trace/StackTracer.h +++ b/kernel/include/trace/StackTracer.h @@ -10,4 +10,6 @@ struct StackTracer private: uintptr_t m_base_pointer; -}; \ No newline at end of file +}; + +bool stack_trace_contains(uintptr_t address); \ No newline at end of file diff --git a/kernel/src/interrupts/Entry.cpp b/kernel/src/interrupts/Entry.cpp index 3c82f386..754a8c6a 100644 --- a/kernel/src/interrupts/Entry.cpp +++ b/kernel/src/interrupts/Entry.cpp @@ -17,8 +17,6 @@ extern "C" void common_handler(Context* context) ASSERT(Interrupts::is_in_handler()); if (context->number >= 0x20 && context->number < 0x30) { - Interrupts::ensure_handler(); // restore the "in-interrupt flag" if an interrupt happened in the middle of this - // one IRQ::interrupt_handler(context); return; } @@ -35,7 +33,6 @@ extern "C" void common_handler(Context* context) StackTracer tracer(context->rbp); tracer.trace_with_ip(context->rip); - Interrupts::ensure_handler(); Scheduler::task_misbehave(context); } } @@ -53,27 +50,14 @@ extern "C" void common_handler(Context* context) StackTracer tracer(context->rbp); tracer.trace_with_ip(context->rip); - Interrupts::ensure_handler(); Scheduler::task_misbehave(context); } } if (context->number == 8) { int_panic(context, "Double fault, halting"); } - if (context->number == 48) - { - Interrupts::ensure_handler(); - Scheduler::task_yield(context); - } - if (context->number == 49) - { - Interrupts::ensure_handler(); - Scheduler::task_exit(context); - } + if (context->number == 48) { Scheduler::task_yield(context); } + if (context->number == 49) { Scheduler::task_exit(context); } if (context->number == 50) { Serial::print((const char*)context->rdi); } - if (context->number == 51) - { - Interrupts::ensure_handler(); - Scheduler::task_sleep(context); - } + if (context->number == 51) { Scheduler::task_sleep(context); } if (context->number == 256) { kwarnln("Unused interrupt"); } return; } \ No newline at end of file diff --git a/kernel/src/interrupts/InterruptEntry.asm b/kernel/src/interrupts/InterruptEntry.asm index bae8999e..8a10aefd 100644 --- a/kernel/src/interrupts/InterruptEntry.asm +++ b/kernel/src/interrupts/InterruptEntry.asm @@ -37,11 +37,6 @@ unused: extern common_handler -section .bss -global __is_in_interrupt_handler -__is_in_interrupt_handler: - resb 1 - section .text global asm_common asm_common: @@ -68,8 +63,6 @@ asm_common: mov r8, cr2 push r8 - mov BYTE [__is_in_interrupt_handler], 1 - mov rdi, rsp call common_handler @@ -83,8 +76,6 @@ _asm_interrupt_exit: mov ds, ax mov es, ax - mov BYTE [__is_in_interrupt_handler], 0 - pop r15 pop r14 pop r13 diff --git a/kernel/src/interrupts/Interrupts.cpp b/kernel/src/interrupts/Interrupts.cpp index 4ebd98d2..d7d6b779 100644 --- a/kernel/src/interrupts/Interrupts.cpp +++ b/kernel/src/interrupts/Interrupts.cpp @@ -1,4 +1,5 @@ #include "interrupts/Interrupts.h" +#include "trace/StackTracer.h" void Interrupts::disable() { @@ -10,15 +11,11 @@ void Interrupts::enable() asm volatile("sti"); } -extern char __is_in_interrupt_handler; +extern int _asm_interrupt_exit; + bool Interrupts::is_in_handler() { - return __is_in_interrupt_handler; -} - -void Interrupts::ensure_handler() -{ - __is_in_interrupt_handler = true; + return stack_trace_contains((uintptr_t)&_asm_interrupt_exit); } void Interrupts::return_from_handler(Context* context) diff --git a/kernel/src/trace/StackTracer.cpp b/kernel/src/trace/StackTracer.cpp index 731f2629..18d1fe9b 100644 --- a/kernel/src/trace/StackTracer.cpp +++ b/kernel/src/trace/StackTracer.cpp @@ -35,4 +35,17 @@ void StackTracer::trace_with_ip(uintptr_t ip) get_symbol_name(ip, symbol_name); printf("%lx: %s\n", ip, symbol_name); trace(); +} + +bool stack_trace_contains(uintptr_t address) +{ + uintptr_t base_pointer; + asm volatile("mov %%rbp, %0" : "=r"(base_pointer)); + stackframe* frame = (stackframe*)base_pointer; + while (frame && (uint64_t)frame > 0xfffffffff8000000) + { + if (frame->instruction == address) return true; + frame = frame->next; + } + return false; } \ No newline at end of file