Commit 3ab24add authored by Nifou's avatar Nifou

More stable kernel

*  Improve kernel panic detection
*  Prevent registers mangling during context switch
parent 12a2f2d7
......@@ -27,7 +27,11 @@ use x86_64::{
use super::id::IrqId;
use super::idt::PICS;
use crate::{
memory::{table::TemporaryPage, PAGE_SIZE, TMP_PAGE_ADDR},
memory::{
table::TemporaryPage,
PAGE_SIZE, TMP_PAGE_ADDR,
KERNEL_START_VIRT, KERNEL_SIZE,
},
tasking::{
memory::MemoryArea,
scheduler::{FIRST_TIME, PROCESSES, SCHEDULER},
......@@ -64,16 +68,9 @@ fn end(id: IrqId) {
/// - Save the current context (registers)
/// - Choose the next thread (with the scheduler)
/// - Load the new context
#[naked]
pub extern "x86-interrupt" fn timer_interrupt_handler(_: &mut InterruptStackFrame) {
unsafe {
// Save registers which will be modified during the next lines (see this function with a
// disassembler)
llvm_asm!("
sub rsp, 16
push rdi
push rsi
push rdx"
llvm_asm!("sub rsp, 0x10"
: : : : "intel", "volatile");
}
......@@ -86,42 +83,48 @@ pub extern "x86-interrupt" fn timer_interrupt_handler(_: &mut InterruptStackFram
llvm_asm!("
// Registers (store the kstack address in rdi because this register
// will be restored later)
mov qword ptr [rdi + 8], rbp
mov qword ptr [rdi + 16], r15
mov qword ptr [rdi + 24], r14
mov qword ptr [rdi + 32], r13
mov qword ptr [rdi + 40], r12
mov qword ptr [rdi + 48], r11
mov qword ptr [rdi + 56], r10
mov qword ptr [rdi + 64], r9
mov qword ptr [rdi + 72], r8
mov qword ptr [rdi + 0x8], rbp
mov qword ptr [rdi + 0x10], r15
mov qword ptr [rdi + 0x18], r14
mov qword ptr [rdi + 0x20], r13
mov qword ptr [rdi + 0x28], r12
mov qword ptr [rdi + 0x30], r11
mov qword ptr [rdi + 0x38], r10
mov qword ptr [rdi + 0x40], r9
mov qword ptr [rdi + 0x48], r8
mov r15, rdi
// Restore the saved registers
// Restore the saved registers (not visible here because it is added with the `x86-interrupt` function type)
pop rax
pop rcx
pop rdx
pop rsi
pop rdi
pop r8
pop r9
pop r10
pop r11
// Registers (store the kstack address in r15 because this register is
// already saved)
mov qword ptr [r15 + 80], rsi
mov qword ptr [r15 + 88], rdi
mov qword ptr [r15 + 96], rdx
mov qword ptr [r15 + 104], rcx
mov qword ptr [r15 + 112], rbx
mov qword ptr [r15 + 120], rax
mov qword ptr [r15 + 0x50], rsi
mov qword ptr [r15 + 0x58], rdi
mov qword ptr [r15 + 0x60], rdx
mov qword ptr [r15 + 0x68], rcx
mov qword ptr [r15 + 0x70], rbx
mov qword ptr [r15 + 0x78], rax
// Stack frame
mov rax, qword ptr [rsp + 16]
mov qword ptr [r15 + 128], rax
mov rax, qword ptr [rsp + 24]
mov qword ptr [r15 + 136], rax
mov rax, qword ptr [rsp + 32]
mov qword ptr [r15 + 144], rax
mov rax, qword ptr [rsp + 40]
mov qword ptr [r15 + 152], rax
mov rax, qword ptr [rsp + 48]
mov qword ptr [r15 + 160], rax"
mov rax, qword ptr [rsp + 0x50]
mov qword ptr [r15 + 0x80], rax
mov rax, qword ptr [rsp + 0x58]
mov qword ptr [r15 + 0x88], rax
mov rax, qword ptr [rsp + 0x60]
mov qword ptr [r15 + 0x90], rax
mov rax, qword ptr [rsp + 0x68]
mov qword ptr [r15 + 0x98], rax
mov rax, qword ptr [rsp + 0x70]
mov qword ptr [r15 + 0xa0], rax"
:
: "{rdi}"(get_kstack())
:
......@@ -484,8 +487,8 @@ pub extern "x86-interrupt" fn page_fault_handler(
}
if handled == false {
let processes = PROCESSES.read();
if processes.is_empty() {
if stack_frame.instruction_pointer.as_u64() >= KERNEL_START_VIRT
&& stack_frame.instruction_pointer.as_u64() <= KERNEL_START_VIRT + KERNEL_SIZE {
// The page fault is generated by the kernel
//
// KERNEL PANIC!
......@@ -497,8 +500,6 @@ pub extern "x86-interrupt" fn page_fault_handler(
);
stop();
} else {
drop(processes);
// The page fault is generated by a userspace program, send the SIGSEGV signal
send_signal(
Signal::SIGSEGV,
......
......@@ -25,16 +25,14 @@
/// sends a signal to it.
macro_rules! fault {
($signal: ident, $stack: ident, $kernel_panic_code: block) => {
let processes = PROCESSES.read();
if processes.is_empty() {
// The fault is caused by the kernel
if $stack.instruction_pointer.as_u64() >= KERNEL_START_VIRT
&& $stack.instruction_pointer.as_u64() <= KERNEL_START_VIRT + KERNEL_SIZE {
// The page fault is generated by the kernel
//
// KERNEL PANIC!
$kernel_panic_code
stop();
} else {
drop(processes);
// The page fault is generated by a userspace program, send the SIGSEGV signal
send_signal(
Signal::$signal,
......
......@@ -66,8 +66,10 @@ pub fn exit(all_threads: bool) {
if all_threads {
// Remove all threads of the process
processes.get_mut(&pid).unwrap().threads.iter().for_each(|t| {
SCHEDULER.get().get(*t).unwrap().exit();
SCHEDULER.get().remove(*t);
if let Some(thread) = SCHEDULER.get().get(*t) {
thread.exit();
SCHEDULER.get().remove(*t);
}
});
processes.get_mut(&pid).unwrap().threads.clear();
} else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment