aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-02-23 21:51:57 +0530
committerBobby <[email protected]>2026-02-23 21:51:57 +0530
commit9194625251d7f14f7cb1d6d032bac7933b33c652 (patch)
treea17f08757d78f580f4f91c298e6637d08c89ded9
parent366cad124438667e36b08dbf1be3e9a11753401d (diff)
downloadakiba-9194625251d7f14f7cb1d6d032bac7933b33c652.tar.xz
akiba-9194625251d7f14f7cb1d6d032bac7933b33c652.zip
fix: Prevent crash by skipping destruction of current kata's page table in cleanup
-rw-r--r--mirai/crimson/exception.zig25
-rw-r--r--mirai/kata/memory.zig10
2 files changed, 27 insertions, 8 deletions
diff --git a/mirai/crimson/exception.zig b/mirai/crimson/exception.zig
index 67147f7..9c74569 100644
--- a/mirai/crimson/exception.zig
+++ b/mirai/crimson/exception.zig
@@ -42,18 +42,31 @@ const NAMES = [_][]const u8{
"Reserved",
};
+var in_exception: bool = false;
+
export fn exception_handler(frame_ptr: u64) void {
const frame = @as(*types.ExceptionFrame, @ptrFromInt(frame_ptr));
+ // Prevent infinite recursion if exception handler itself faults
+ if (in_exception) {
+ serial.print("NESTED EXCEPTION - HALTING\n");
+ while (true) {
+ asm volatile ("cli; hlt");
+ }
+ }
+ in_exception = true;
+
// Handle page faults - check for stack growth
if (frame.int_num == 14) {
const cr2 = memory.read_page_fault_address();
const is_not_present = (frame.error_code & 1) == 0;
+ const is_rsvd = (frame.error_code & 8) != 0;
// Check if fault is in user stack region (demand paging)
if (sensei.get_current_kata()) |kata| {
- if (cr2 >= kata.user_stack_bottom and cr2 < kata.user_stack_top and is_not_present) {
+ if (cr2 >= kata.user_stack_bottom and cr2 < kata.user_stack_top and is_not_present and !is_rsvd) {
if (kata_memory.grow_stack(kata, cr2)) {
+ in_exception = false;
return;
}
}
@@ -82,6 +95,7 @@ export fn exception_handler(frame_ptr: u64) void {
if (sensei.get_current_kata()) |kata| {
serial.printf("Stack: bottom={x} committed={x} top={x}\n", .{ kata.user_stack_bottom, kata.user_stack_committed, kata.user_stack_top });
+ serial.printf("Kata: id={x} PT={x}\n", .{ kata.id, kata.page_table });
}
serial.print("Fault type: ");
@@ -100,6 +114,9 @@ export fn exception_handler(frame_ptr: u64) void {
} else {
serial.print(", Kernel mode");
}
+ if ((frame.error_code & 8) != 0) {
+ serial.print(", RESERVED BIT SET");
+ }
serial.print("\n");
serial.printf("CR3 (page table): {x}\n", .{memory.read_page_table_base()});
@@ -115,9 +132,5 @@ export fn exception_handler(frame_ptr: u64) void {
serial.printf("R12: {x} R13: {x}\n", .{ frame.r12, frame.r13 });
serial.printf("R14: {x} R15: {x}\n", .{ frame.r14, frame.r15 });
- if (frame.int_num < NAMES.len) {
- panic.collapse(NAMES[frame.int_num], null);
- } else {
- panic.collapse("Unknown Exception", null);
- }
+ panic.collapse(if (frame.int_num < NAMES.len) NAMES[frame.int_num] else "Unknown Exception", null);
}
diff --git a/mirai/kata/memory.zig b/mirai/kata/memory.zig
index 880cf63..ac16d76 100644
--- a/mirai/kata/memory.zig
+++ b/mirai/kata/memory.zig
@@ -1,5 +1,6 @@
//! Kata memory management
+const asm_memory = @import("../asm/memory.zig");
const memory_const = @import("../common/constants/memory.zig");
const memory_limits = @import("../common/limits/memory.zig");
const paging = @import("../memory/paging.zig");
@@ -219,7 +220,13 @@ pub fn load_segment(
pub fn cleanup(kata: *types.Kata) void {
if (kata.page_table != 0) {
- paging.destroy_page_table(kata.page_table);
+ // CRITICAL: If we're currently using this kata's page table,
+ // we CANNOT destroy it - we'd be freeing pages while CR3 points to them.
+ // Skip destruction (memory leak) to prevent crash.
+ const current_cr3 = asm_memory.read_page_table_base();
+ if (current_cr3 != kata.page_table) {
+ paging.destroy_page_table(kata.page_table);
+ }
kata.page_table = 0;
}
kata.stack_top = 0;
@@ -229,7 +236,6 @@ pub fn cleanup(kata: *types.Kata) void {
}
pub fn grow_stack(kata: *types.Kata, fault_addr: u64) bool {
- const asm_memory = @import("../asm/memory.zig");
const page_addr = fault_addr & ~@as(u64, 0xFFF);
if (page_addr >= kata.user_stack_committed or page_addr < kata.user_stack_bottom) {