Extract x86-specific exception handling in aster-nix

This commit is contained in:
YanWQ-monad
2024-07-19 15:42:53 +08:00
committed by Tate, Hongliang Tian
parent a997d9f0b0
commit 4d36dd541f
7 changed files with 86 additions and 142 deletions

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: MPL-2.0
use ostd::{
cpu::{CpuExceptionInfo, RawGeneralRegs, UserContext, PAGE_FAULT},
cpu::{CpuException, CpuExceptionInfo, RawGeneralRegs, UserContext},
Pod,
};
@ -107,7 +107,7 @@ impl TryFrom<&CpuExceptionInfo> for PageFaultInfo {
type Error = ();
fn try_from(value: &CpuExceptionInfo) -> Result<Self, ()> {
if value.cpu_exception() != PAGE_FAULT {
if value.cpu_exception() != CpuException::PAGE_FAULT {
return Err(());
}

View File

@ -1,8 +1,10 @@
// 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 {
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);
}
}
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)
}
}