Interrupts: Remove ensure_handler and use a more reliable way of detecting if we are in a handler

This commit is contained in:
apio 2022-09-29 18:35:51 +02:00
parent 6c036dfe99
commit 46f459337c
6 changed files with 23 additions and 37 deletions

View File

@ -7,6 +7,5 @@ namespace Interrupts
void disable(); void disable();
bool is_in_handler(); bool is_in_handler();
void ensure_handler();
void return_from_handler(Context* context); void return_from_handler(Context* context);
} }

View File

@ -10,4 +10,6 @@ struct StackTracer
private: private:
uintptr_t m_base_pointer; uintptr_t m_base_pointer;
}; };
bool stack_trace_contains(uintptr_t address);

View File

@ -17,8 +17,6 @@ extern "C" void common_handler(Context* context)
ASSERT(Interrupts::is_in_handler()); ASSERT(Interrupts::is_in_handler());
if (context->number >= 0x20 && context->number < 0x30) 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); IRQ::interrupt_handler(context);
return; return;
} }
@ -35,7 +33,6 @@ extern "C" void common_handler(Context* context)
StackTracer tracer(context->rbp); StackTracer tracer(context->rbp);
tracer.trace_with_ip(context->rip); tracer.trace_with_ip(context->rip);
Interrupts::ensure_handler();
Scheduler::task_misbehave(context); Scheduler::task_misbehave(context);
} }
} }
@ -53,27 +50,14 @@ extern "C" void common_handler(Context* context)
StackTracer tracer(context->rbp); StackTracer tracer(context->rbp);
tracer.trace_with_ip(context->rip); tracer.trace_with_ip(context->rip);
Interrupts::ensure_handler();
Scheduler::task_misbehave(context); Scheduler::task_misbehave(context);
} }
} }
if (context->number == 8) { int_panic(context, "Double fault, halting"); } if (context->number == 8) { int_panic(context, "Double fault, halting"); }
if (context->number == 48) if (context->number == 48) { Scheduler::task_yield(context); }
{ if (context->number == 49) { Scheduler::task_exit(context); }
Interrupts::ensure_handler();
Scheduler::task_yield(context);
}
if (context->number == 49)
{
Interrupts::ensure_handler();
Scheduler::task_exit(context);
}
if (context->number == 50) { Serial::print((const char*)context->rdi); } if (context->number == 50) { Serial::print((const char*)context->rdi); }
if (context->number == 51) if (context->number == 51) { Scheduler::task_sleep(context); }
{
Interrupts::ensure_handler();
Scheduler::task_sleep(context);
}
if (context->number == 256) { kwarnln("Unused interrupt"); } if (context->number == 256) { kwarnln("Unused interrupt"); }
return; return;
} }

View File

@ -37,11 +37,6 @@ unused:
extern common_handler extern common_handler
section .bss
global __is_in_interrupt_handler
__is_in_interrupt_handler:
resb 1
section .text section .text
global asm_common global asm_common
asm_common: asm_common:
@ -68,8 +63,6 @@ asm_common:
mov r8, cr2 mov r8, cr2
push r8 push r8
mov BYTE [__is_in_interrupt_handler], 1
mov rdi, rsp mov rdi, rsp
call common_handler call common_handler
@ -83,8 +76,6 @@ _asm_interrupt_exit:
mov ds, ax mov ds, ax
mov es, ax mov es, ax
mov BYTE [__is_in_interrupt_handler], 0
pop r15 pop r15
pop r14 pop r14
pop r13 pop r13

View File

@ -1,4 +1,5 @@
#include "interrupts/Interrupts.h" #include "interrupts/Interrupts.h"
#include "trace/StackTracer.h"
void Interrupts::disable() void Interrupts::disable()
{ {
@ -10,15 +11,11 @@ void Interrupts::enable()
asm volatile("sti"); asm volatile("sti");
} }
extern char __is_in_interrupt_handler; extern int _asm_interrupt_exit;
bool Interrupts::is_in_handler() bool Interrupts::is_in_handler()
{ {
return __is_in_interrupt_handler; return stack_trace_contains((uintptr_t)&_asm_interrupt_exit);
}
void Interrupts::ensure_handler()
{
__is_in_interrupt_handler = true;
} }
void Interrupts::return_from_handler(Context* context) void Interrupts::return_from_handler(Context* context)

View File

@ -35,4 +35,17 @@ void StackTracer::trace_with_ip(uintptr_t ip)
get_symbol_name(ip, symbol_name); get_symbol_name(ip, symbol_name);
printf("%lx: %s\n", ip, symbol_name); printf("%lx: %s\n", ip, symbol_name);
trace(); 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;
} }