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();
bool is_in_handler();
void ensure_handler();
void return_from_handler(Context* context);
}

View File

@ -11,3 +11,5 @@ struct StackTracer
private:
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());
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;
}

View File

@ -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

View File

@ -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)

View File

@ -36,3 +36,16 @@ void StackTracer::trace_with_ip(uintptr_t ip)
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;
}