[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