feature: x86_64 user pf handling

This commit is contained in:
2022-03-22 18:44:10 +02:00
parent a318bf0c2c
commit 200f18b425
2 changed files with 35 additions and 10 deletions
+28 -3
View File
@@ -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);
}
+7 -7
View File
@@ -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<Tid, Errno> {