From 200f18b425f6b39c840998035e021e6abcb0fea2 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Tue, 22 Mar 2022 18:44:10 +0200 Subject: [PATCH] feature: x86_64 user pf handling --- kernel/src/arch/x86_64/exception.rs | 31 ++++++++++++++++++++++++++--- kernel/src/proc/process.rs | 14 ++++++------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/kernel/src/arch/x86_64/exception.rs b/kernel/src/arch/x86_64/exception.rs index f0d8e65..39a8edf 100644 --- a/kernel/src/arch/x86_64/exception.rs +++ b/kernel/src/arch/x86_64/exception.rs @@ -2,6 +2,9 @@ use crate::arch::x86_64; use crate::debug::Level; use crate::dev::irq::{IntController, IrqContext}; use core::arch::{asm, global_asm}; +use libsys::{error::Errno, signal::Signal}; +use crate::mem::{self, virt::table::Space}; +use crate::proc::{Thread, sched}; #[derive(Debug)] struct ExceptionFrame { @@ -48,7 +51,7 @@ fn pfault_access_type(code: u64) -> &'static str { } } -fn pfault_dump(level: Level, frame: &ExceptionFrame, cr2: u64) { +fn pfault_dump(level: Level, frame: &ExceptionFrame, cr2: usize) { println!(level, "\x1B[41;1mPage fault:"); println!( level, @@ -61,8 +64,30 @@ fn pfault_dump(level: Level, frame: &ExceptionFrame, cr2: u64) { #[no_mangle] extern "C" fn __x86_64_exception_handler(frame: &mut ExceptionFrame) { if frame.err_no == 14 { - // TODO userspace page faults - let cr2 = pfault_read_cr2(); + let cr2 = pfault_read_cr2() as usize; + + if cr2 < mem::KERNEL_OFFSET && sched::is_ready() { + let thread = Thread::current(); + let proc = thread.owner().unwrap(); + + let res = proc.manipulate_space(|space| { + space.try_cow_copy(cr2)?; + // unsafe { + // intrin::flush_tlb_asid(asid); + // } + Result::<(), Errno>::Ok(()) + }); + + if res.is_err() { + errorln!("Page fault at {:#x} in user {:?}", frame.rip, thread.owner_id()); + pfault_dump(Level::Error, frame, cr2); + proc.enter_fault_signal(thread, Signal::SegmentationFault); + } + + return; + } + + errorln!("Unresolved page fault:"); pfault_dump(Level::Error, frame, cr2); } diff --git a/kernel/src/proc/process.rs b/kernel/src/proc/process.rs index 94c0436..6a0f653 100644 --- a/kernel/src/proc/process.rs +++ b/kernel/src/proc/process.rs @@ -152,13 +152,13 @@ impl Process { } } - // /// Immediately delivers a signal to requested thread - // pub fn enter_fault_signal(&self, thread: ThreadRef, signal: Signal) { - // let mut lock = self.inner.lock(); - // let table = Self::space_phys(&lock); - // drop(lock); - // thread.enter_signal(signal, table); - // } + /// Immediately delivers a signal to requested thread + pub fn enter_fault_signal(&self, thread: ThreadRef, signal: Signal) { + let mut lock = self.inner.lock(); + let table = Self::space_phys(&mut lock); + drop(lock); + thread.enter_signal(signal, table); + } /// Crates a new thread in the process pub fn new_user_thread(&self, entry: usize, stack: usize, arg: usize) -> Result {