unsafe fn pf_handler(a: &ExceptionArguments) {
    use crate::arch::kcb;

    let err = PageFaultError::from_bits_truncate(a.exception as u32);
    let faulting_address = x86::controlregs::cr2();
    let kcb = get_kcb();

    // If this is a user-mode page-fault make sure it's not a spurious
    // page-fault by not having a replica in-sync with others
    if err.contains(PageFaultError::US) {
        let faulting_address_va = VAddr::from(faulting_address);
        let pid = kcb
            .current_pid()
            .expect("A pid must be set in this if branch (US bit set in page-fault error)");

        match nrproc::NrProcess::<Ring3Process>::resolve(pid, faulting_address_va) {
            Ok((paddr, rights)) => {
                // TODO(harden): We probably want to warn/abort if we get many
                // "spurious" pfaults for the same addr in quick succession: one
                // bug I encountered is when I accidentially made executor
                // objects with the PML4 base address of the same process but
                // from another replica, in that case it will end up pfaulting
                // here until the other replica (by chance) advances and this
                // code doesn't really do anything...
                trace!(
                    "Spurious page-fault, after resolve page-table is up to date {} {} -> {:#x} {:#b} on {}",
                    pid, faulting_address_va, paddr, rights, kcb.arch.hwthread_id()
                );
                let r = kcb_iret_handle(kcb);
                r.resume()
            }
            Err(_) => {
                // unresolved page-fault, proceed with abort below
            }
        }
    }

    sprintln!("[IRQ] Page Fault on {}", kcb.arch.id());
    sprintln!("{}", err);

    // Enable user-space access
    x86::current::rflags::stac();

    for i in 0..32 {
        let ptr = (a.rsp as *const u64).offset(i);
        sprintln!("stack[{}] = {:#x}", i, *ptr);
    }

    // Print where the fault happend in the address-space:
    let faulting_address = x86::controlregs::cr2();
    sprint!("Faulting address: {:#x}", faulting_address);
    sprint!(" Instruction Pointer: {:#x}", a.rip);

    /*
    if !err.contains(PageFaultError::US) {
        kcb::try_get_kcb().map(|k| {
            sprintln!(
                " (in ELF: {:#x})",
                faulting_address - k.kernel_args().kernel_elf_offset.as_usize()
            )
        });
    } else {
        sprintln!("");
    }
    */

    // Print the RIP that triggered the fault:
    sprint!("Instruction Pointer: {:#x}", a.rip);
    if !err.contains(PageFaultError::US) {
        kcb::try_get_kcb().map(|k| {
            sprintln!(
                " (in ELF: {:#x})",
                a.rip - k.arch.kernel_args().kernel_elf_offset.as_u64()
            )
        });
    } else {
        sprintln!("");
    }

    sprintln!("{:?}", a);
    let kcb = get_kcb();
    sprintln!("Register State:\n{:?}", kcb.arch.save_area);
    if !kcb.in_panic_mode {
        kcb.arch.save_area.as_ref().map(|sa| {
            backtrace_from(sa.rbp, sa.rsp, sa.rip);
        });
    }

    debug::shutdown(ExitReason::PageFault);
}
/// Handler for unexpected page-faults.
///
/// TODO: Right now we terminate kernel.
/// Should abort process and resume.
Handler for unexpected page-faults.
TODO: Right now we terminate kernel.
Should abort process and resume.
Handler for unexpected page - faults . TODO : Right now we terminate kernel . Should abort process and resume .
unsafe fn pf_handler(a: &ExceptionArguments) {
    use crate::arch::kcb;
    let err = PageFaultError::from_bits_truncate(a.exception as u32);
    let faulting_address = x86::controlregs::cr2();
    let kcb = get_kcb();
    // If this is a user-mode page-fault make sure it's not a spurious
    // page-fault by not having a replica in-sync with others
    if err.contains(PageFaultError::US) {
        let faulting_address_va = VAddr::from(faulting_address);
        let pid = kcb
            .current_pid()
            .expect("A pid must be set in this if branch (US bit set in page-fault error)");
        match nrproc::NrProcess::<Ring3Process>::resolve(pid, faulting_address_va) {
            Ok((paddr, rights)) => {
                // TODO(harden): We probably want to warn/abort if we get many
                // "spurious" pfaults for the same addr in quick succession: one
                // bug I encountered is when I accidentially made executor
                // objects with the PML4 base address of the same process but
                // from another replica, in that case it will end up pfaulting
                // here until the other replica (by chance) advances and this
                // code doesn't really do anything...
                trace!(
                    "Spurious page-fault, after resolve page-table is up to date {} {} -> {:#x} {:#b} on {}",
                    pid, faulting_address_va, paddr, rights, kcb.arch.hwthread_id()
                );
                let r = kcb_iret_handle(kcb);
                r.resume()
            }
            Err(_) => {
                // unresolved page-fault, proceed with abort below
            }
        }
    }
    sprintln!("[IRQ] Page Fault on {}", kcb.arch.id());
    sprintln!("{}", err);
    // Enable user-space access
    x86::current::rflags::stac();
    for i in 0..32 {
        let ptr = (a.rsp as *const u64).offset(i);
        sprintln!("stack[{}] = {:#x}", i, *ptr);
    }
    // Print where the fault happend in the address-space:
    let faulting_address = x86::controlregs::cr2();
    sprint!("Faulting address: {:#x}", faulting_address);
    sprint!(" Instruction Pointer: {:#x}", a.rip);
    /*
    if !err.contains(PageFaultError::US) {
        kcb::try_get_kcb().map(|k| {
            sprintln!(
                " (in ELF: {:#x})",
                faulting_address - k.kernel_args().kernel_elf_offset.as_usize()
            )
        });
    } else {
        sprintln!("");
    }
    */
    // Print the RIP that triggered the fault:
    sprint!("Instruction Pointer: {:#x}", a.rip);
    if !err.contains(PageFaultError::US) {
        kcb::try_get_kcb().map(|k| {
            sprintln!(
                " (in ELF: {:#x})",
                a.rip - k.arch.kernel_args().kernel_elf_offset.as_u64()
            )
        });
    } else {
        sprintln!("");
    }
    sprintln!("{:?}", a);
    let kcb = get_kcb();
    sprintln!("Register State:\n{:?}", kcb.arch.save_area);
    if !kcb.in_panic_mode {
        kcb.arch.save_area.as_ref().map(|sa| {
            backtrace_from(sa.rbp, sa.rsp, sa.rip);
        });
    }
    debug::shutdown(ExitReason::PageFault);
}
unsafe fn pf_handler ( a : & ExceptionArguments ) { use crate :: arch :: kcb ; let err = PageFaultError :: from_bits_truncate ( a . exception as u32 ) ; let faulting_address = x86 :: controlregs :: cr2 ( ) ; let kcb = get_kcb ( ) ; // If this is a user-mode page-fault make sure it's not a spurious // page-fault by not having a replica in-sync with others if err . contains ( PageFaultError :: US ) { let faulting_address_va = VAddr :: from ( faulting_address ) ; let pid = kcb . current_pid ( ) . expect ( " " ) ; match nrproc :: NrProcess :: < Ring3Process > :: resolve ( pid , faulting_address_va ) { Ok ( ( paddr , rights ) ) => { // TODO(harden): We probably want to warn/abort if we get many // "spurious" pfaults for the same addr in quick succession: one // bug I encountered is when I accidentially made executor // objects with the PML4 base address of the same process but // from another replica, in that case it will end up pfaulting // here until the other replica (by chance) advances and this // code doesn't really do anything... trace ! ( " " pid faulting_address_va paddr rights kcb arch hwthread_id ( ) ) ; let r = kcb_iret_handle ( kcb ) ; r . resume ( ) } Err ( _ ) => { // unresolved page-fault, proceed with abort below } } } sprintln ! ( " " kcb arch id ( ) ) ; sprintln ! ( " " err ) ; // Enable user-space access x86 :: current :: rflags :: stac ( ) ; for i in 0 .. 32 { let ptr = ( a . rsp as * const u64 ) . offset ( i ) ; sprintln ! ( " " i ptr ) ; } // Print where the fault happend in the address-space: let faulting_address = x86 :: controlregs :: cr2 ( ) ; sprint ! ( " " faulting_address ) ; sprint ! ( " " a rip ) ; /*
    if !err.contains(PageFaultError::US) {
        kcb::try_get_kcb().map(|k| {
            sprintln!(
                " (in ELF: {:#x})",
                faulting_address - k.kernel_args().kernel_elf_offset.as_usize()
            )
        });
    } else {
        sprintln!("");
    }
    */ // Print the RIP that triggered the fault: sprint ! ( " " a rip ) ; if ! err . contains ( PageFaultError :: US ) { kcb :: try_get_kcb ( ) . map ( | k | { sprintln ! ( " " a rip k arch kernel_args ( ) kernel_elf_offset as_u64 ( ) ) } ) ; } else { sprintln ! ( " " ) ; } sprintln ! ( " " a ) ; let kcb = get_kcb ( ) ; sprintln ! ( " \n " kcb arch save_area ) ; if ! kcb . in_panic_mode { kcb . arch . save_area . as_ref ( ) . map ( | sa | { backtrace_from ( sa . rbp , sa . rsp , sa . rip ) ; } ) ; } debug :: shutdown ( ExitReason :: PageFault ) ; }
Handler for unexpected page-faults.
Handler for unexpected page - faults .
a
&ExceptionArguments
a
&ExceptionArguments