mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-11 22:36:48 +00:00
Extract x86-specific exception handling in aster-nix
This commit is contained in:
parent
a997d9f0b0
commit
4d36dd541f
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use ostd::{
|
use ostd::{
|
||||||
cpu::{CpuExceptionInfo, RawGeneralRegs, UserContext, PAGE_FAULT},
|
cpu::{CpuException, CpuExceptionInfo, RawGeneralRegs, UserContext},
|
||||||
Pod,
|
Pod,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ impl TryFrom<&CpuExceptionInfo> for PageFaultInfo {
|
|||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn try_from(value: &CpuExceptionInfo) -> Result<Self, ()> {
|
fn try_from(value: &CpuExceptionInfo) -> Result<Self, ()> {
|
||||||
if value.cpu_exception() != PAGE_FAULT {
|
if value.cpu_exception() != CpuException::PAGE_FAULT {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use ostd::cpu::UserContext;
|
use ostd::cpu::{CpuException, CpuExceptionInfo, UserContext};
|
||||||
|
|
||||||
use crate::process::signal::{sig_num::SigNum, SignalContext};
|
use crate::process::signal::{
|
||||||
|
constants::*, sig_num::SigNum, signals::fault::FaultSignal, SignalContext,
|
||||||
|
};
|
||||||
|
|
||||||
impl SignalContext for UserContext {
|
impl SignalContext for UserContext {
|
||||||
fn set_arguments(&mut self, sig_num: SigNum, siginfo_addr: usize, ucontext_addr: usize) {
|
fn set_arguments(&mut self, sig_num: SigNum, siginfo_addr: usize, ucontext_addr: usize) {
|
||||||
@ -11,3 +13,30 @@ impl SignalContext for UserContext {
|
|||||||
self.set_rdx(ucontext_addr);
|
self.set_rdx(ucontext_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<&CpuExceptionInfo> for FaultSignal {
|
||||||
|
fn from(trap_info: &CpuExceptionInfo) -> Self {
|
||||||
|
let exception = CpuException::to_cpu_exception(trap_info.id as u16).unwrap();
|
||||||
|
let (num, code, addr) = match exception {
|
||||||
|
CpuException::DIVIDE_BY_ZERO => (SIGFPE, FPE_INTDIV, None),
|
||||||
|
CpuException::X87_FLOATING_POINT_EXCEPTION
|
||||||
|
| CpuException::SIMD_FLOATING_POINT_EXCEPTION => (SIGFPE, FPE_FLTDIV, None),
|
||||||
|
CpuException::BOUND_RANGE_EXCEEDED => (SIGSEGV, SEGV_BNDERR, None),
|
||||||
|
CpuException::ALIGNMENT_CHECK => (SIGBUS, BUS_ADRALN, None),
|
||||||
|
CpuException::INVALID_OPCODE => (SIGILL, ILL_ILLOPC, None),
|
||||||
|
CpuException::GENERAL_PROTECTION_FAULT => (SIGBUS, BUS_ADRERR, None),
|
||||||
|
CpuException::PAGE_FAULT => {
|
||||||
|
const PF_ERR_FLAG_PRESENT: usize = 1usize << 0;
|
||||||
|
let code = if trap_info.error_code & PF_ERR_FLAG_PRESENT != 0 {
|
||||||
|
SEGV_ACCERR
|
||||||
|
} else {
|
||||||
|
SEGV_MAPERR
|
||||||
|
};
|
||||||
|
let addr = Some(trap_info.page_fault_addr as u64);
|
||||||
|
(SIGSEGV, code, addr)
|
||||||
|
}
|
||||||
|
_ => panic!("Exception cannot be a signal"),
|
||||||
|
};
|
||||||
|
FaultSignal::new(num, code, addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,7 +11,7 @@ use id_alloc::IdAlloc;
|
|||||||
use ostd::{
|
use ostd::{
|
||||||
arch::{
|
arch::{
|
||||||
timer::{self, TIMER_FREQ},
|
timer::{self, TIMER_FREQ},
|
||||||
x86::trap::is_kernel_interrupted,
|
trap::is_kernel_interrupted,
|
||||||
},
|
},
|
||||||
sync::Mutex,
|
sync::Mutex,
|
||||||
};
|
};
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use ostd::cpu::{
|
|
||||||
CpuException, CpuExceptionInfo, ALIGNMENT_CHECK, BOUND_RANGE_EXCEEDED, DIVIDE_BY_ZERO,
|
|
||||||
GENERAL_PROTECTION_FAULT, INVALID_OPCODE, PAGE_FAULT, SIMD_FLOATING_POINT_EXCEPTION,
|
|
||||||
X87_FLOATING_POINT_EXCEPTION,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::Signal;
|
use super::Signal;
|
||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::signal::{c_types::siginfo_t, constants::*, sig_num::SigNum},
|
process::signal::{c_types::siginfo_t, sig_num::SigNum},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct FaultSignal {
|
pub struct FaultSignal {
|
||||||
num: SigNum,
|
num: SigNum,
|
||||||
@ -19,30 +14,7 @@ pub struct FaultSignal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FaultSignal {
|
impl FaultSignal {
|
||||||
pub fn new(trap_info: &CpuExceptionInfo) -> FaultSignal {
|
pub fn new(num: SigNum, code: i32, addr: Option<u64>) -> FaultSignal {
|
||||||
debug!("Trap id: {}", trap_info.id);
|
|
||||||
let exception = CpuException::to_cpu_exception(trap_info.id as u16).unwrap();
|
|
||||||
let (num, code, addr) = match *exception {
|
|
||||||
DIVIDE_BY_ZERO => (SIGFPE, FPE_INTDIV, None),
|
|
||||||
X87_FLOATING_POINT_EXCEPTION | SIMD_FLOATING_POINT_EXCEPTION => {
|
|
||||||
(SIGFPE, FPE_FLTDIV, None)
|
|
||||||
}
|
|
||||||
BOUND_RANGE_EXCEEDED => (SIGSEGV, SEGV_BNDERR, None),
|
|
||||||
ALIGNMENT_CHECK => (SIGBUS, BUS_ADRALN, None),
|
|
||||||
INVALID_OPCODE => (SIGILL, ILL_ILLOPC, None),
|
|
||||||
GENERAL_PROTECTION_FAULT => (SIGBUS, BUS_ADRERR, None),
|
|
||||||
PAGE_FAULT => {
|
|
||||||
const PF_ERR_FLAG_PRESENT: usize = 1usize << 0;
|
|
||||||
let code = if trap_info.error_code & PF_ERR_FLAG_PRESENT != 0 {
|
|
||||||
SEGV_ACCERR
|
|
||||||
} else {
|
|
||||||
SEGV_MAPERR
|
|
||||||
};
|
|
||||||
let addr = Some(trap_info.page_fault_addr as u64);
|
|
||||||
(SIGSEGV, code, addr)
|
|
||||||
}
|
|
||||||
_ => panic!("Exception cannot be a signal"),
|
|
||||||
};
|
|
||||||
FaultSignal { num, code, addr }
|
FaultSignal { num, code, addr }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,61 +73,19 @@ pub(crate) fn handle_page_fault_from_vmar(
|
|||||||
|
|
||||||
/// generate a fault signal for current process.
|
/// generate a fault signal for current process.
|
||||||
fn generate_fault_signal(trap_info: &CpuExceptionInfo, ctx: &Context) {
|
fn generate_fault_signal(trap_info: &CpuExceptionInfo, ctx: &Context) {
|
||||||
let signal = FaultSignal::new(trap_info);
|
let signal = FaultSignal::from(trap_info);
|
||||||
ctx.posix_thread.enqueue_signal(Box::new(signal));
|
ctx.posix_thread.enqueue_signal(Box::new(signal));
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! log_trap_common {
|
|
||||||
($exception_name: ident, $trap_info: ident) => {
|
|
||||||
trace!(
|
|
||||||
"[Trap][{}][err = {}]",
|
|
||||||
stringify!($exception_name),
|
|
||||||
$trap_info.error_code
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log_trap_info(trap_info: &CpuExceptionInfo) {
|
fn log_trap_info(trap_info: &CpuExceptionInfo) {
|
||||||
match trap_info.cpu_exception() {
|
if let Ok(page_fault_info) = PageFaultInfo::try_from(trap_info) {
|
||||||
DIVIDE_BY_ZERO => log_trap_common!(DIVIDE_BY_ZERO, trap_info),
|
trace!(
|
||||||
DEBUG => log_trap_common!(DEBUG, trap_info),
|
"[Trap][PAGE_FAULT][page fault addr = 0x{:x}, err = {}]",
|
||||||
NON_MASKABLE_INTERRUPT => log_trap_common!(NON_MASKABLE_INTERRUPT, trap_info),
|
trap_info.page_fault_addr,
|
||||||
BREAKPOINT => log_trap_common!(BREAKPOINT, trap_info),
|
trap_info.error_code
|
||||||
OVERFLOW => log_trap_common!(OVERFLOW, trap_info),
|
);
|
||||||
BOUND_RANGE_EXCEEDED => log_trap_common!(BOUND_RANGE_EXCEEDED, trap_info),
|
} else {
|
||||||
INVALID_OPCODE => log_trap_common!(INVALID_OPCODE, trap_info),
|
let exception = trap_info.cpu_exception();
|
||||||
DEVICE_NOT_AVAILABLE => log_trap_common!(DEVICE_NOT_AVAILABLE, trap_info),
|
trace!("[Trap][{exception:?}][err = {}]", trap_info.error_code)
|
||||||
DOUBLE_FAULT => log_trap_common!(DOUBLE_FAULT, trap_info),
|
|
||||||
COPROCESSOR_SEGMENT_OVERRUN => log_trap_common!(COPROCESSOR_SEGMENT_OVERRUN, trap_info),
|
|
||||||
INVALID_TSS => log_trap_common!(INVALID_TSS, trap_info),
|
|
||||||
SEGMENT_NOT_PRESENT => log_trap_common!(SEGMENT_NOT_PRESENT, trap_info),
|
|
||||||
STACK_SEGMENT_FAULT => log_trap_common!(STACK_SEGMENT_FAULT, trap_info),
|
|
||||||
GENERAL_PROTECTION_FAULT => log_trap_common!(GENERAL_PROTECTION_FAULT, trap_info),
|
|
||||||
PAGE_FAULT => {
|
|
||||||
trace!(
|
|
||||||
"[Trap][{}][page fault addr = 0x{:x}, err = {}]",
|
|
||||||
stringify!(PAGE_FAULT),
|
|
||||||
trap_info.page_fault_addr,
|
|
||||||
trap_info.error_code
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// 15 reserved
|
|
||||||
X87_FLOATING_POINT_EXCEPTION => log_trap_common!(X87_FLOATING_POINT_EXCEPTION, trap_info),
|
|
||||||
ALIGNMENT_CHECK => log_trap_common!(ALIGNMENT_CHECK, trap_info),
|
|
||||||
MACHINE_CHECK => log_trap_common!(MACHINE_CHECK, trap_info),
|
|
||||||
SIMD_FLOATING_POINT_EXCEPTION => log_trap_common!(SIMD_FLOATING_POINT_EXCEPTION, trap_info),
|
|
||||||
VIRTUALIZATION_EXCEPTION => log_trap_common!(VIRTUALIZATION_EXCEPTION, trap_info),
|
|
||||||
CONTROL_PROTECTION_EXCEPTION => log_trap_common!(CONTROL_PROTECTION_EXCEPTION, trap_info),
|
|
||||||
HYPERVISOR_INJECTION_EXCEPTION => {
|
|
||||||
log_trap_common!(HYPERVISOR_INJECTION_EXCEPTION, trap_info)
|
|
||||||
}
|
|
||||||
VMM_COMMUNICATION_EXCEPTION => log_trap_common!(VMM_COMMUNICATION_EXCEPTION, trap_info),
|
|
||||||
SECURITY_EXCEPTION => log_trap_common!(SECURITY_EXCEPTION, trap_info),
|
|
||||||
_ => {
|
|
||||||
info!(
|
|
||||||
"[Trap][Unknown trap type][id = {}, err = {}]",
|
|
||||||
trap_info.id, trap_info.error_code
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ use core::{
|
|||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
use num_derive::FromPrimitive;
|
||||||
|
use num_traits::FromPrimitive;
|
||||||
use x86::bits64::segmentation::wrfsbase;
|
use x86::bits64::segmentation::wrfsbase;
|
||||||
use x86_64::registers::rflags::RFlags;
|
use x86_64::registers::rflags::RFlags;
|
||||||
|
|
||||||
@ -109,41 +111,37 @@ impl UserContextApiInternal for UserContext {
|
|||||||
// set ID flag which means cpu support CPUID instruction
|
// set ID flag which means cpu support CPUID instruction
|
||||||
self.user_context.general.rflags |= (RFlags::INTERRUPT_FLAG | RFlags::ID).bits() as usize;
|
self.user_context.general.rflags |= (RFlags::INTERRUPT_FLAG | RFlags::ID).bits() as usize;
|
||||||
|
|
||||||
let return_reason: ReturnReason;
|
|
||||||
const SYSCALL_TRAPNUM: u16 = 0x100;
|
const SYSCALL_TRAPNUM: u16 = 0x100;
|
||||||
|
|
||||||
// return when it is syscall or cpu exception type is Fault or Trap.
|
// return when it is syscall or cpu exception type is Fault or Trap.
|
||||||
loop {
|
let return_reason = loop {
|
||||||
scheduler::might_preempt();
|
scheduler::might_preempt();
|
||||||
self.user_context.run();
|
self.user_context.run();
|
||||||
match CpuException::to_cpu_exception(self.user_context.trap_num as u16) {
|
match CpuException::to_cpu_exception(self.user_context.trap_num as u16) {
|
||||||
Some(exception) => {
|
Some(exception) => {
|
||||||
#[cfg(feature = "cvm_guest")]
|
#[cfg(feature = "cvm_guest")]
|
||||||
if *exception == VIRTUALIZATION_EXCEPTION {
|
if exception == CpuException::VIRTUALIZATION_EXCEPTION {
|
||||||
handle_virtualization_exception(self);
|
handle_virtualization_exception(self);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if exception.typ == CpuExceptionType::FaultOrTrap
|
match exception.typ() {
|
||||||
|| exception.typ == CpuExceptionType::Fault
|
CpuExceptionType::FaultOrTrap
|
||||||
|| exception.typ == CpuExceptionType::Trap
|
| CpuExceptionType::Trap
|
||||||
{
|
| CpuExceptionType::Fault => break ReturnReason::UserException,
|
||||||
return_reason = ReturnReason::UserException;
|
_ => (),
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
if self.user_context.trap_num as u16 == SYSCALL_TRAPNUM {
|
if self.user_context.trap_num as u16 == SYSCALL_TRAPNUM {
|
||||||
return_reason = ReturnReason::UserSyscall;
|
break ReturnReason::UserSyscall;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
call_irq_callback_functions(&self.as_trap_frame(), self.as_trap_frame().trap_num);
|
call_irq_callback_functions(&self.as_trap_frame(), self.as_trap_frame().trap_num);
|
||||||
if has_kernel_event() {
|
if has_kernel_event() {
|
||||||
return_reason = ReturnReason::KernelEvent;
|
break ReturnReason::KernelEvent;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
crate::arch::irq::enable_local();
|
crate::arch::irq::enable_local();
|
||||||
if return_reason == ReturnReason::UserException {
|
if return_reason == ReturnReason::UserException {
|
||||||
@ -212,39 +210,26 @@ pub enum CpuExceptionType {
|
|||||||
Reserved,
|
Reserved,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CPU exception.
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
|
||||||
pub struct CpuException {
|
|
||||||
/// The ID of the CPU exception.
|
|
||||||
pub number: u16,
|
|
||||||
/// The type of the CPU exception.
|
|
||||||
pub typ: CpuExceptionType,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Copy from: https://veykril.github.io/tlborm/decl-macros/building-blocks/counting.html#slice-length
|
|
||||||
macro_rules! replace_expr {
|
|
||||||
($_t:tt $sub:expr) => {
|
|
||||||
$sub
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Copy from: https://veykril.github.io/tlborm/decl-macros/building-blocks/counting.html#slice-length
|
|
||||||
macro_rules! count_tts {
|
|
||||||
($($tts:tt)*) => {<[()]>::len(&[$(replace_expr!($tts ())),*])};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! define_cpu_exception {
|
macro_rules! define_cpu_exception {
|
||||||
( $([ $name: ident = $exception_num:tt, $exception_type:tt]),* ) => {
|
( $([ $name: ident = $exception_id:tt, $exception_type:tt]),* ) => {
|
||||||
const EXCEPTION_LIST : [CpuException;count_tts!($($name)*)] = [
|
/// CPU exception.
|
||||||
$($name,)*
|
#[allow(non_camel_case_types)]
|
||||||
];
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, FromPrimitive)]
|
||||||
$(
|
pub enum CpuException {
|
||||||
#[doc = concat!("The ", stringify!($name), " exception")]
|
$(
|
||||||
pub const $name : CpuException = CpuException{
|
#[doc = concat!("The ", stringify!($name), " exception")]
|
||||||
number: $exception_num,
|
$name = $exception_id,
|
||||||
typ: CpuExceptionType::$exception_type,
|
)*
|
||||||
};
|
}
|
||||||
)*
|
|
||||||
|
impl CpuException {
|
||||||
|
/// The type of the CPU exception.
|
||||||
|
pub fn typ(&self) -> CpuExceptionType {
|
||||||
|
match self {
|
||||||
|
$( CpuException::$name => CpuExceptionType::$exception_type, )*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,19 +299,19 @@ bitflags! {
|
|||||||
impl CpuException {
|
impl CpuException {
|
||||||
/// Checks if the given `trap_num` is a valid CPU exception.
|
/// Checks if the given `trap_num` is a valid CPU exception.
|
||||||
pub fn is_cpu_exception(trap_num: u16) -> bool {
|
pub fn is_cpu_exception(trap_num: u16) -> bool {
|
||||||
trap_num < EXCEPTION_LIST.len() as u16
|
Self::to_cpu_exception(trap_num).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maps a `trap_num` to its corresponding CPU exception.
|
/// Maps a `trap_num` to its corresponding CPU exception.
|
||||||
pub fn to_cpu_exception(trap_num: u16) -> Option<&'static CpuException> {
|
pub fn to_cpu_exception(trap_num: u16) -> Option<CpuException> {
|
||||||
EXCEPTION_LIST.get(trap_num as usize)
|
FromPrimitive::from_u16(trap_num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CpuExceptionInfo {
|
impl CpuExceptionInfo {
|
||||||
/// Get corresponding CPU exception
|
/// Get corresponding CPU exception
|
||||||
pub fn cpu_exception(&self) -> CpuException {
|
pub fn cpu_exception(&self) -> CpuException {
|
||||||
EXCEPTION_LIST[self.id]
|
CpuException::to_cpu_exception(self.id as u16).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ use log::debug;
|
|||||||
|
|
||||||
use super::ex_table::ExTable;
|
use super::ex_table::ExTable;
|
||||||
use crate::{
|
use crate::{
|
||||||
cpu::{CpuException, CpuExceptionInfo, PageFaultErrorCode, PAGE_FAULT},
|
cpu::{CpuException, CpuExceptionInfo, PageFaultErrorCode},
|
||||||
cpu_local_cell,
|
cpu_local_cell,
|
||||||
mm::{
|
mm::{
|
||||||
kspace::{KERNEL_PAGE_TABLE, LINEAR_MAPPING_BASE_VADDR, LINEAR_MAPPING_VADDR_RANGE},
|
kspace::{KERNEL_PAGE_TABLE, LINEAR_MAPPING_BASE_VADDR, LINEAR_MAPPING_VADDR_RANGE},
|
||||||
@ -40,7 +40,7 @@ use crate::{
|
|||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(feature = "cvm_guest")] {
|
if #[cfg(feature = "cvm_guest")] {
|
||||||
use tdx_guest::{tdcall, tdx_is_enabled, handle_virtual_exception};
|
use tdx_guest::{tdcall, tdx_is_enabled, handle_virtual_exception};
|
||||||
use crate::arch::{cpu::VIRTUALIZATION_EXCEPTION, tdx_guest::TrapFrameWrapper};
|
use crate::arch::tdx_guest::TrapFrameWrapper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,13 +223,13 @@ extern "sysv64" fn trap_handler(f: &mut TrapFrame) {
|
|||||||
if CpuException::is_cpu_exception(f.trap_num as u16) {
|
if CpuException::is_cpu_exception(f.trap_num as u16) {
|
||||||
match CpuException::to_cpu_exception(f.trap_num as u16).unwrap() {
|
match CpuException::to_cpu_exception(f.trap_num as u16).unwrap() {
|
||||||
#[cfg(feature = "cvm_guest")]
|
#[cfg(feature = "cvm_guest")]
|
||||||
&VIRTUALIZATION_EXCEPTION => {
|
CpuException::VIRTUALIZATION_EXCEPTION => {
|
||||||
let ve_info = tdcall::get_veinfo().expect("#VE handler: fail to get VE info\n");
|
let ve_info = tdcall::get_veinfo().expect("#VE handler: fail to get VE info\n");
|
||||||
let mut trapframe_wrapper = TrapFrameWrapper(&mut *f);
|
let mut trapframe_wrapper = TrapFrameWrapper(&mut *f);
|
||||||
handle_virtual_exception(&mut trapframe_wrapper, &ve_info);
|
handle_virtual_exception(&mut trapframe_wrapper, &ve_info);
|
||||||
*f = *trapframe_wrapper.0;
|
*f = *trapframe_wrapper.0;
|
||||||
}
|
}
|
||||||
&PAGE_FAULT => {
|
CpuException::PAGE_FAULT => {
|
||||||
let page_fault_addr = x86_64::registers::control::Cr2::read_raw();
|
let page_fault_addr = x86_64::registers::control::Cr2::read_raw();
|
||||||
// The actual user space implementation should be responsible
|
// The actual user space implementation should be responsible
|
||||||
// for providing mechanism to treat the 0 virtual address.
|
// for providing mechanism to treat the 0 virtual address.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user