feature: x86_64 user pf handling
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user