[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH 1/6] kernel2: handle_exception nach arch verschoben
* handle_exception ist architektur abhängig und gehört daher in
den arch/* abschnitt
Signed-off-by: Andreas Freimuth <m.nemo@xxxxxxx>
---
src/kernel2/include/arch/amd64/cpu.h | 5 ++
src/kernel2/src/arch/amd64/im/im.c | 72 ++++++++++++++++++++++++-
src/kernel2/src/arch/i386/interrupts/im.c | 84 +++++++++++++++++++++++++++++
src/kernel2/src/interrupts/im.c | 84 +----------------------------
4 files changed, 161 insertions(+), 84 deletions(-)
diff --git a/src/kernel2/include/arch/amd64/cpu.h b/src/kernel2/include/arch/amd64/cpu.h
index 0826c32..b5214c4 100644
--- a/src/kernel2/include/arch/amd64/cpu.h
+++ b/src/kernel2/include/arch/amd64/cpu.h
@@ -107,5 +107,10 @@ uint64_t cpu_read_msr(uint32_t reg);
mmc_context_t cpu_get_context();
void cpu_set_context(mmc_context_t context);
+/*
+ * Aktiviert die I/O-Bitmap fuer den Prozess
+ */
+void io_activate_bitmap(pm_process_t* task);
+
#endif //ifndef _CPU_H_
diff --git a/src/kernel2/src/arch/amd64/im/im.c b/src/kernel2/src/arch/amd64/im/im.c
index 59008f9..0a58beb 100644
--- a/src/kernel2/src/arch/amd64/im/im.c
+++ b/src/kernel2/src/arch/amd64/im/im.c
@@ -40,6 +40,8 @@
#include "im.h"
#include "apic.h"
#include "pic.h"
+#include "debug.h"
+#include "syscall.h"
#define IDT_GATE_COUNT 256
#define IDT_GATE_TYPE_INT 0xE
@@ -77,6 +79,7 @@ typedef struct {
idt_gate_t idt[IDT_GATE_COUNT];
bool use_apic;
+extern void increase_user_stack_size(pm_thread_t* task_ptr, int pages);
static void idt_set_gate(size_t interrupt, vaddr_t handler, uint8_t privilege_level);
// Die ASM-Stubs
@@ -659,4 +662,71 @@ void im_end_of_interrupt(uint8_t interrupt)
}
}
-
+
+/**
+ * Verarbeitet eine CPU-Exception
+ */
+void handle_exception(interrupt_stack_frame_t* isf, uint8_t int_num)
+{
+ uintptr_t cr2;
+ asm("mov %%cr2, %0" : "=r" (cr2));
+
+// kprintf("user_stack_bottom = %x\n",
+// current_thread->user_stack_bottom);
+
+ if (int_num == 0x0d) {
+ // Prüfen, ob der #GP möglicherweise durch eine nicht geladene
+ // I/O-Bitmap verurscht worden ist
+ if (cpu_get_current()->tss.io_bit_map_offset ==
+ TSS_IO_BITMAP_NOT_LOADED)
+ {
+ io_activate_bitmap(current_process);
+ return;
+ }
+ }
+
+ if (int_num == 0x0e) {
+ // Überprüfen ob der Pagefault durch einen Stackoverflow
+ // hervorgerufen wurde. Falls ja: Stack vergrößern und weitermachen
+ if ((cr2 <= isf->rsp + 0x800) && (cr2 >= isf->rsp - 0x20)
+ && (current_thread != NULL)
+ && ((void*) cr2 >= current_thread->user_stack_bottom - 0x1000000)
+ && ((void*) cr2 < current_thread->user_stack_bottom))
+ {
+ increase_user_stack_size(current_thread, 1);
+ return;
+ }
+ }
+
+ // Exception
+ kprintf("\033[1;41m");
+ kprintf("[CPU%d] Exception %d; Error Code = 0x%lx\n",
+ cpu_get_current()->id, int_num, isf->error_code);
+
+ kprintf("PID %d: %s\n",
+ current_process->pid, current_process->cmdline);
+ cpu_dump(isf);
+ kprintf("\033[0;40m");
+
+ // Ein Stacktrace dürfen wir nur ausgeben, wenn kein Pagefault wegen
+ // dem Stack aufgetreten ist!
+ if (!((cr2 < isf->rsp + 800) && (cr2 >= isf->rsp -0x20))) {
+ stack_backtrace(isf->rbp, isf->rip);
+ }
+
+ // Wenn die Exception im Kernel passiert ist, geben wir auf
+ if ((isf->cs & 0x03) == 0) {
+ // Hier werden alle Prozessoren zum halten gebracht
+ if (cpu_count > 1) {
+ apic_ipi_broadcast(0xF0, true);
+ }
+
+ // Aber da das ohne APIC nicht so funktioniert, wird das noch
+ // abgefangen.
+ asm("cli; hlt");
+ }
+
+ // Ansonsten wird nur der aktuelle Task beendet
+ syscall_pm_exit_process();
+}
+
diff --git a/src/kernel2/src/arch/i386/interrupts/im.c b/src/kernel2/src/arch/i386/interrupts/im.c
index 08642fa..413ef15 100644
--- a/src/kernel2/src/arch/i386/interrupts/im.c
+++ b/src/kernel2/src/arch/i386/interrupts/im.c
@@ -41,6 +41,8 @@
#include "im.h"
#include "apic.h"
#include "pic.h"
+#include "debug.h"
+#include "syscall.h"
#define IDT_GATE_COUNT 256
#define IDT_GATE_TYPE_TASK 0x5
@@ -727,3 +729,85 @@ void im_end_of_interrupt(uint8_t interrupt)
}
}
+extern void increase_user_stack_size(pm_thread_t* task_ptr, int pages);
+extern int vm86_exception(interrupt_stack_frame_t* isf);
+
+/**
+ * Verarbeitet eine CPU-Exception
+ */
+void handle_exception(interrupt_stack_frame_t* isf, uint8_t int_num)
+{
+ uintptr_t cr2;
+ asm("mov %%cr2, %0" : "=r" (cr2));
+
+// kprintf("user_stack_bottom = %x\n",
+// current_thread->user_stack_bottom);
+
+ // Prüfen, ob ein VM86-Task die Exception ausgelöst hat
+ // Falls ja lassen wir sie vom VM86-Code behandeln, wenn er kann
+ if (current_thread->vm86) {
+ if (vm86_exception(isf)) {
+ return;
+ }
+ }
+
+ if (int_num == 0x0d) {
+ // Prüfen, ob der #GP möglicherweise durch eine nicht geladene
+ // I/O-Bitmap verurscht worden ist
+ if (cpu_get_current()->tss.io_bit_map_offset ==
+ TSS_IO_BITMAP_NOT_LOADED)
+ {
+ io_activate_bitmap(current_process);
+ return;
+ }
+ }
+
+ if (int_num == 0x0e) {
+ // Überprüfen ob der Pagefault durch einen Stackoverflow
+ // hervorgerufen wurde. Falls ja: Stack vergrößern und weitermachen
+ if ((cr2 <= isf->esp + 0x800) && (cr2 >= isf->esp - 0x20)
+ && (current_thread != NULL)
+ && ((void*) cr2 >= current_thread->user_stack_bottom - 0x1000000)
+ && ((void*) cr2 < current_thread->user_stack_bottom))
+ {
+ increase_user_stack_size(current_thread, 1);
+ return;
+ }
+ }
+
+ // Exception
+ kprintf("\033[1;41m");
+ kprintf("[CPU%d] Exception %d; Error Code = 0x%x\n",
+ cpu_get_current()->id, int_num, isf->error_code);
+
+ kprintf("PID %d: %s\n",
+ current_process->pid, current_process->cmdline);
+ cpu_dump(isf);
+ kprintf("\033[0;40m");
+
+ // Ein Stacktrace dürfen wir nur ausgeben, wenn kein Pagefault wegen
+ // dem Stack aufgetreten ist!
+ if (!((cr2 < isf->esp + 800) && (cr2 >= isf->esp -0x20))) {
+ // Und für VM86 müssten wir wenigstens noch das Segment
+ // berücksichtigen, aber eigentlich brauchen wir ihn da gar nicht
+ if ((isf->eflags & 0x20000) == 0) {
+ stack_backtrace(isf->ebp, isf->eip);
+ }
+ }
+
+ // Wenn die Exception im Kernel passiert ist, geben wir auf
+ if ((isf->cs & 0x03) == 0) {
+ // Hier werden alle Prozessoren zum halten gebracht
+ if (cpu_count > 1) {
+ apic_ipi_broadcast(0xF0, true);
+ }
+
+ // Aber da das ohne APIC nicht so funktioniert, wird das noch
+ // abgefangen.
+ asm("cli; hlt");
+ }
+
+ // Ansonsten wird nur der aktuelle Task beendet
+ syscall_pm_exit_process();
+}
+
diff --git a/src/kernel2/src/interrupts/im.c b/src/kernel2/src/interrupts/im.c
index 97862ac..9879f98 100644
--- a/src/kernel2/src/interrupts/im.c
+++ b/src/kernel2/src/interrupts/im.c
@@ -71,89 +71,7 @@ void im_send_interrupts(void);
bool fastrpc_irq(pm_process_t* callee, size_t metadata_size, void* metadata,
size_t data_size, void* data, uint8_t irq);
-extern void increase_user_stack_size(pm_thread_t* task_ptr, int pages);
-extern int vm86_exception(interrupt_stack_frame_t* isf);
-
-/**
- * Verarbeitet eine CPU-Exception
- */
-static void handle_exception(interrupt_stack_frame_t* isf, uint8_t int_num)
-{
- uintptr_t cr2;
- asm("mov %%cr2, %0" : "=r" (cr2));
-
-// kprintf("user_stack_bottom = %x\n",
-// current_thread->user_stack_bottom);
-
-#if CONFIG_ARCH == ARCH_I386
- // Pruefen, ob ein VM86-Task die Exception ausgeloest hat
- // Falls ja lassen wir sie vom VM86-Code behandeln, wenn er kann
- if (current_thread->vm86) {
- if (vm86_exception(isf)) {
- return;
- }
- }
-#endif
-
- if (int_num == 0x0d) {
- // Pruefen, ob der #GP moeglicherweise durch eine nicht geladene
- // I/O-Bitmap verurscht worden ist
- if (cpu_get_current()->tss.io_bit_map_offset ==
- TSS_IO_BITMAP_NOT_LOADED)
- {
- io_activate_bitmap(current_process);
- return;
- }
- }
-
- if (int_num == 0x0e) {
- // Ueberprüfen ob der Pagefault durch einen Stackoverflow
- // hervorgerufen wurde. Falls ja: Stack vergroessern und weitermachen
- if ((cr2 <= isf->esp + 0x800) && (cr2 >= isf->esp - 0x20)
- && (current_thread != NULL)
- && ((void*) cr2 >= current_thread->user_stack_bottom - 0x1000000)
- && ((void*) cr2 < current_thread->user_stack_bottom))
- {
- increase_user_stack_size(current_thread, 1);
- return;
- }
- }
-
- // Exception
- kprintf("\033[1;41m");
- kprintf("[CPU%d] Exception %d; Error Code = 0x%x\n",
- cpu_get_current()->id, int_num, isf->error_code);
-
- kprintf("PID %d: %s\n",
- current_process->pid, current_process->cmdline);
- cpu_dump(isf);
- kprintf("\033[0;40m");
-
- // Ein Stacktrace duerfen wir nur ausgeben, wenn kein Pagefault wegen
- // dem Stack aufgetreten ist!
- if (!((cr2 < isf->esp + 800) && (cr2 >= isf->esp -0x20))) {
- // Und fuer VM86 muessten wir wenigstens noch das Segment
- // beruecksichtigen, aber eigentlich brauchen wir ihn da gar nicht
- if ((isf->eflags & 0x20000) == 0) {
- stack_backtrace(isf->ebp, isf->eip);
- }
- }
-
- // Wenn die Exception im Kernel passiert ist, geben wir auf
- if ((isf->cs & 0x03) == 0) {
- // Hier werden alle Prozessoren zum halten gebracht
- if (cpu_count > 1) {
- apic_ipi_broadcast(0xF0, true);
- }
-
- // Aber da das ohne APIC nicht so funktioniert, wird das noch
- // abgefangen.
- asm("cli; hlt");
- }
-
- // Ansonsten wird nur der aktuelle Task beendet
- syscall_pm_exit_process();
-}
+void handle_exception(interrupt_stack_frame_t* isf, uint8_t int_num);
/**
* Behandelt alle Interrupts. Wird aus den Interrupt-Stubs aufgerufen.
--
1.7.4.4