Clean up `trapframe` items
This commit is contained in:
parent
6f2725419f
commit
0fce977b40
|
|
@ -3,7 +3,7 @@
|
|||
use alloc::{format, string::String};
|
||||
|
||||
use ostd::{
|
||||
cpu::context::{CpuExceptionInfo, RawGeneralRegs, UserContext},
|
||||
cpu::context::{CpuExceptionInfo, GeneralRegs, UserContext},
|
||||
Pod,
|
||||
};
|
||||
|
||||
|
|
@ -122,11 +122,11 @@ macro_rules! copy_gp_regs {
|
|||
}
|
||||
|
||||
impl GpRegs {
|
||||
pub fn copy_to_raw(&self, dst: &mut RawGeneralRegs) {
|
||||
pub fn copy_to_raw(&self, dst: &mut GeneralRegs) {
|
||||
copy_gp_regs!(self, dst);
|
||||
}
|
||||
|
||||
pub fn copy_from_raw(&mut self, src: &RawGeneralRegs) {
|
||||
pub fn copy_from_raw(&mut self, src: &GeneralRegs) {
|
||||
copy_gp_regs!(src, self);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use alloc::{
|
|||
};
|
||||
|
||||
use ostd::{
|
||||
cpu::context::{cpuid, CpuException, CpuExceptionInfo, RawGeneralRegs, UserContext},
|
||||
cpu::context::{cpuid, CpuException, CpuExceptionInfo, GeneralRegs, UserContext},
|
||||
Pod,
|
||||
};
|
||||
|
||||
|
|
@ -102,11 +102,11 @@ macro_rules! copy_gp_regs {
|
|||
}
|
||||
|
||||
impl GpRegs {
|
||||
pub fn copy_to_raw(&self, dst: &mut RawGeneralRegs) {
|
||||
pub fn copy_to_raw(&self, dst: &mut GeneralRegs) {
|
||||
copy_gp_regs!(self, dst);
|
||||
}
|
||||
|
||||
pub fn copy_from_raw(&mut self, src: &RawGeneralRegs) {
|
||||
pub fn copy_from_raw(&mut self, src: &GeneralRegs) {
|
||||
copy_gp_regs!(src, self);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use aster_rights::WriteOp;
|
||||
use ostd::{
|
||||
cpu::context::{FpuState, RawGeneralRegs, UserContext},
|
||||
cpu::context::{FpuState, GeneralRegs, UserContext},
|
||||
user::UserContextApi,
|
||||
};
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ fn do_execve(
|
|||
// set signal disposition to default
|
||||
process.sig_dispositions().lock().inherit();
|
||||
// set cpu context to default
|
||||
*user_context.general_regs_mut() = RawGeneralRegs::default();
|
||||
*user_context.general_regs_mut() = GeneralRegs::default();
|
||||
user_context.set_tls_pointer(0);
|
||||
*user_context.fpu_state_mut() = FpuState::default();
|
||||
// FIXME: how to reset the FPU state correctly? Before returning to the user space,
|
||||
|
|
|
|||
|
|
@ -6,16 +6,15 @@ use core::fmt::Debug;
|
|||
|
||||
use riscv::register::scause::{Exception, Interrupt, Trap};
|
||||
|
||||
pub use crate::arch::trap::GeneralRegs as RawGeneralRegs;
|
||||
use crate::{
|
||||
arch::{
|
||||
timer::handle_timer_interrupt,
|
||||
trap::{TrapFrame, UserContext as RawUserContext},
|
||||
trap::{RawUserContext, TrapFrame},
|
||||
},
|
||||
user::{ReturnReason, UserContextApi, UserContextApiInternal},
|
||||
};
|
||||
|
||||
/// Cpu context, including both general-purpose registers and FPU state.
|
||||
/// Userspace CPU context, including both general-purpose registers and FPU state.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct UserContext {
|
||||
|
|
@ -25,6 +24,45 @@ pub struct UserContext {
|
|||
cpu_exception_info: CpuExceptionInfo,
|
||||
}
|
||||
|
||||
/// General registers.
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
#[expect(missing_docs)]
|
||||
pub struct GeneralRegs {
|
||||
pub zero: usize,
|
||||
pub ra: usize,
|
||||
pub sp: usize,
|
||||
pub gp: usize,
|
||||
pub tp: usize,
|
||||
pub t0: usize,
|
||||
pub t1: usize,
|
||||
pub t2: usize,
|
||||
pub s0: usize,
|
||||
pub s1: usize,
|
||||
pub a0: usize,
|
||||
pub a1: usize,
|
||||
pub a2: usize,
|
||||
pub a3: usize,
|
||||
pub a4: usize,
|
||||
pub a5: usize,
|
||||
pub a6: usize,
|
||||
pub a7: usize,
|
||||
pub s2: usize,
|
||||
pub s3: usize,
|
||||
pub s4: usize,
|
||||
pub s5: usize,
|
||||
pub s6: usize,
|
||||
pub s7: usize,
|
||||
pub s8: usize,
|
||||
pub s9: usize,
|
||||
pub s10: usize,
|
||||
pub s11: usize,
|
||||
pub t3: usize,
|
||||
pub t4: usize,
|
||||
pub t5: usize,
|
||||
pub t6: usize,
|
||||
}
|
||||
|
||||
/// CPU exception information.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
|
|
@ -66,12 +104,12 @@ impl CpuExceptionInfo {
|
|||
|
||||
impl UserContext {
|
||||
/// Returns a reference to the general registers.
|
||||
pub fn general_regs(&self) -> &RawGeneralRegs {
|
||||
pub fn general_regs(&self) -> &GeneralRegs {
|
||||
&self.user_context.general
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the general registers
|
||||
pub fn general_regs_mut(&mut self) -> &mut RawGeneralRegs {
|
||||
pub fn general_regs_mut(&mut self) -> &mut GeneralRegs {
|
||||
&mut self.user_context.general
|
||||
}
|
||||
|
||||
|
|
@ -166,15 +204,15 @@ impl UserContextApi for UserContext {
|
|||
}
|
||||
|
||||
fn set_instruction_pointer(&mut self, ip: usize) {
|
||||
self.user_context.set_ip(ip);
|
||||
self.user_context.sepc = ip;
|
||||
}
|
||||
|
||||
fn stack_pointer(&self) -> usize {
|
||||
self.user_context.get_sp()
|
||||
self.sp()
|
||||
}
|
||||
|
||||
fn set_stack_pointer(&mut self, sp: usize) {
|
||||
self.user_context.set_sp(sp);
|
||||
self.set_sp(sp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ mod trap;
|
|||
|
||||
use riscv::register::scause::Interrupt;
|
||||
use spin::Once;
|
||||
pub use trap::{GeneralRegs, TrapFrame, UserContext};
|
||||
pub(super) use trap::RawUserContext;
|
||||
pub use trap::TrapFrame;
|
||||
|
||||
use super::cpu::context::CpuExceptionInfo;
|
||||
use crate::cpu_local_cell;
|
||||
|
|
@ -15,8 +16,8 @@ cpu_local_cell! {
|
|||
static IS_KERNEL_INTERRUPTED: bool = false;
|
||||
}
|
||||
|
||||
/// Initialize interrupt handling on RISC-V.
|
||||
pub unsafe fn init() {
|
||||
/// Initializes interrupt handling on RISC-V.
|
||||
pub(crate) unsafe fn init() {
|
||||
self::trap::init();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
use core::arch::{asm, global_asm};
|
||||
|
||||
use crate::Pod;
|
||||
use crate::arch::cpu::context::GeneralRegs;
|
||||
|
||||
#[cfg(target_arch = "riscv32")]
|
||||
global_asm!(
|
||||
|
|
@ -86,136 +86,29 @@ pub struct TrapFrame {
|
|||
}
|
||||
|
||||
/// Saved registers on a trap.
|
||||
#[derive(Debug, Default, Clone, Copy, Pod)]
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct UserContext {
|
||||
pub(in crate::arch) struct RawUserContext {
|
||||
/// General registers
|
||||
pub general: GeneralRegs,
|
||||
pub(in crate::arch) general: GeneralRegs,
|
||||
/// Supervisor Status
|
||||
pub sstatus: usize,
|
||||
pub(in crate::arch) sstatus: usize,
|
||||
/// Supervisor Exception Program Counter
|
||||
pub sepc: usize,
|
||||
pub(in crate::arch) sepc: usize,
|
||||
}
|
||||
|
||||
impl UserContext {
|
||||
/// Go to user space with the context, and come back when a trap occurs.
|
||||
impl RawUserContext {
|
||||
/// Goes to user space with the context, and comes back when a trap occurs.
|
||||
///
|
||||
/// On return, the context will be reset to the status before the trap.
|
||||
/// Trap reason and error code will be returned.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// use trapframe::{UserContext, GeneralRegs};
|
||||
///
|
||||
/// // init user space context
|
||||
/// let mut context = UserContext {
|
||||
/// general: GeneralRegs {
|
||||
/// sp: 0x10000,
|
||||
/// ..Default::default()
|
||||
/// },
|
||||
/// sepc: 0x1000,
|
||||
/// ..Default::default()
|
||||
/// };
|
||||
/// // go to user
|
||||
/// context.run();
|
||||
/// // back from user
|
||||
/// println!("back from user: {:#x?}", context);
|
||||
/// ```
|
||||
pub fn run(&mut self) {
|
||||
/// Trap reason and error code will be placed at `scause` and `stval`.
|
||||
pub(in crate::arch) fn run(&mut self) {
|
||||
unsafe { run_user(self) }
|
||||
}
|
||||
}
|
||||
|
||||
/// General registers
|
||||
#[derive(Debug, Default, Clone, Copy, Pod)]
|
||||
#[repr(C)]
|
||||
#[expect(missing_docs)]
|
||||
pub struct GeneralRegs {
|
||||
pub zero: usize,
|
||||
pub ra: usize,
|
||||
pub sp: usize,
|
||||
pub gp: usize,
|
||||
pub tp: usize,
|
||||
pub t0: usize,
|
||||
pub t1: usize,
|
||||
pub t2: usize,
|
||||
pub s0: usize,
|
||||
pub s1: usize,
|
||||
pub a0: usize,
|
||||
pub a1: usize,
|
||||
pub a2: usize,
|
||||
pub a3: usize,
|
||||
pub a4: usize,
|
||||
pub a5: usize,
|
||||
pub a6: usize,
|
||||
pub a7: usize,
|
||||
pub s2: usize,
|
||||
pub s3: usize,
|
||||
pub s4: usize,
|
||||
pub s5: usize,
|
||||
pub s6: usize,
|
||||
pub s7: usize,
|
||||
pub s8: usize,
|
||||
pub s9: usize,
|
||||
pub s10: usize,
|
||||
pub s11: usize,
|
||||
pub t3: usize,
|
||||
pub t4: usize,
|
||||
pub t5: usize,
|
||||
pub t6: usize,
|
||||
}
|
||||
|
||||
impl UserContext {
|
||||
/// Get number of syscall
|
||||
pub fn get_syscall_num(&self) -> usize {
|
||||
self.general.a7
|
||||
}
|
||||
|
||||
/// Get return value of syscall
|
||||
pub fn get_syscall_ret(&self) -> usize {
|
||||
self.general.a0
|
||||
}
|
||||
|
||||
/// Set return value of syscall
|
||||
pub fn set_syscall_ret(&mut self, ret: usize) {
|
||||
self.general.a0 = ret;
|
||||
}
|
||||
|
||||
/// Get syscall args
|
||||
pub fn get_syscall_args(&self) -> [usize; 6] {
|
||||
[
|
||||
self.general.a0,
|
||||
self.general.a1,
|
||||
self.general.a2,
|
||||
self.general.a3,
|
||||
self.general.a4,
|
||||
self.general.a5,
|
||||
]
|
||||
}
|
||||
|
||||
/// Set instruction pointer
|
||||
pub fn set_ip(&mut self, ip: usize) {
|
||||
self.sepc = ip;
|
||||
}
|
||||
|
||||
/// Set stack pointer
|
||||
pub fn set_sp(&mut self, sp: usize) {
|
||||
self.general.sp = sp;
|
||||
}
|
||||
|
||||
/// Get stack pointer
|
||||
pub fn get_sp(&self) -> usize {
|
||||
self.general.sp
|
||||
}
|
||||
|
||||
/// Set tls pointer
|
||||
pub fn set_tls(&mut self, tls: usize) {
|
||||
self.general.gp = tls;
|
||||
}
|
||||
}
|
||||
|
||||
#[expect(improper_ctypes)]
|
||||
extern "C" {
|
||||
fn trap_entry();
|
||||
fn run_user(regs: &mut UserContext);
|
||||
fn run_user(regs: &mut RawUserContext);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,10 @@ use x86_64::registers::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
arch::CPU_FEATURES,
|
||||
arch::{
|
||||
trap::{RawUserContext, TrapFrame},
|
||||
CPU_FEATURES,
|
||||
},
|
||||
task::scheduler,
|
||||
trap::call_irq_callback_functions,
|
||||
user::{ReturnReason, UserContextApi, UserContextApiInternal},
|
||||
|
|
@ -38,11 +41,7 @@ cfg_if! {
|
|||
|
||||
pub use x86::cpuid;
|
||||
|
||||
pub use crate::arch::trap::{
|
||||
GeneralRegs as RawGeneralRegs, TrapFrame, UserContext as RawUserContext,
|
||||
};
|
||||
|
||||
/// Cpu context, including both general-purpose registers and FPU state.
|
||||
/// Userspace CPU context, including both general-purpose registers and FPU state.
|
||||
#[derive(Clone, Default, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct UserContext {
|
||||
|
|
@ -51,6 +50,33 @@ pub struct UserContext {
|
|||
cpu_exception_info: CpuExceptionInfo,
|
||||
}
|
||||
|
||||
/// General registers.
|
||||
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
|
||||
#[repr(C)]
|
||||
#[expect(missing_docs)]
|
||||
pub struct GeneralRegs {
|
||||
pub rax: usize,
|
||||
pub rbx: usize,
|
||||
pub rcx: usize,
|
||||
pub rdx: usize,
|
||||
pub rsi: usize,
|
||||
pub rdi: usize,
|
||||
pub rbp: usize,
|
||||
pub rsp: usize,
|
||||
pub r8: usize,
|
||||
pub r9: usize,
|
||||
pub r10: usize,
|
||||
pub r11: usize,
|
||||
pub r12: usize,
|
||||
pub r13: usize,
|
||||
pub r14: usize,
|
||||
pub r15: usize,
|
||||
pub rip: usize,
|
||||
pub rflags: usize,
|
||||
pub fsbase: usize,
|
||||
pub gsbase: usize,
|
||||
}
|
||||
|
||||
/// CPU exception information.
|
||||
#[derive(Clone, Default, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
|
|
@ -65,12 +91,12 @@ pub struct CpuExceptionInfo {
|
|||
|
||||
impl UserContext {
|
||||
/// Returns a reference to the general registers.
|
||||
pub fn general_regs(&self) -> &RawGeneralRegs {
|
||||
pub fn general_regs(&self) -> &GeneralRegs {
|
||||
&self.user_context.general
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the general registers
|
||||
pub fn general_regs_mut(&mut self) -> &mut RawGeneralRegs {
|
||||
pub fn general_regs_mut(&mut self) -> &mut GeneralRegs {
|
||||
&mut self.user_context.general
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use tdx_guest::{
|
|||
handle_virtual_exception as do_handle_virtual_exception, tdcall, TdgVeInfo, TdxTrapFrame,
|
||||
};
|
||||
|
||||
use crate::cpu::context::{RawGeneralRegs, UserContext};
|
||||
use super::{GeneralRegs, UserContext};
|
||||
|
||||
pub(crate) struct VirtualizationExceptionHandler {
|
||||
ve_info: TdgVeInfo,
|
||||
|
|
@ -34,7 +34,7 @@ impl VirtualizationExceptionHandler {
|
|||
}
|
||||
}
|
||||
|
||||
struct GeneralRegsWrapper<'a>(&'a mut RawGeneralRegs);
|
||||
struct GeneralRegsWrapper<'a>(&'a mut GeneralRegs);
|
||||
|
||||
impl TdxTrapFrame for GeneralRegsWrapper<'_> {
|
||||
fn rax(&self) -> usize {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ use cfg_if::cfg_if;
|
|||
use log::debug;
|
||||
use spin::Once;
|
||||
|
||||
use super::ex_table::ExTable;
|
||||
use super::{cpu::context::GeneralRegs, ex_table::ExTable};
|
||||
use crate::{
|
||||
arch::{
|
||||
if_tdx_enabled,
|
||||
|
|
@ -103,7 +103,7 @@ pub struct TrapFrame {
|
|||
pub rflags: usize,
|
||||
}
|
||||
|
||||
/// Initialize interrupt handling on x86_64.
|
||||
/// Initializes interrupt handling on x86_64.
|
||||
///
|
||||
/// This function will:
|
||||
/// - Switch to a new, CPU-local [GDT].
|
||||
|
|
@ -119,7 +119,7 @@ pub struct TrapFrame {
|
|||
/// # Safety
|
||||
///
|
||||
/// This method must be called only in the boot context of each available processor.
|
||||
pub unsafe fn init() {
|
||||
pub(crate) unsafe fn init() {
|
||||
// SAFETY: We're in the boot context, so no preemption can occur.
|
||||
unsafe { gdt::init() };
|
||||
|
||||
|
|
@ -129,90 +129,13 @@ pub unsafe fn init() {
|
|||
unsafe { syscall::init() };
|
||||
}
|
||||
|
||||
/// User space context.
|
||||
/// Userspace context.
|
||||
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
|
||||
#[repr(C)]
|
||||
#[expect(missing_docs)]
|
||||
pub struct UserContext {
|
||||
pub general: GeneralRegs,
|
||||
pub trap_num: usize,
|
||||
pub error_code: usize,
|
||||
}
|
||||
|
||||
/// General registers.
|
||||
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
|
||||
#[repr(C)]
|
||||
#[expect(missing_docs)]
|
||||
pub struct GeneralRegs {
|
||||
pub rax: usize,
|
||||
pub rbx: usize,
|
||||
pub rcx: usize,
|
||||
pub rdx: usize,
|
||||
pub rsi: usize,
|
||||
pub rdi: usize,
|
||||
pub rbp: usize,
|
||||
pub rsp: usize,
|
||||
pub r8: usize,
|
||||
pub r9: usize,
|
||||
pub r10: usize,
|
||||
pub r11: usize,
|
||||
pub r12: usize,
|
||||
pub r13: usize,
|
||||
pub r14: usize,
|
||||
pub r15: usize,
|
||||
pub rip: usize,
|
||||
pub rflags: usize,
|
||||
pub fsbase: usize,
|
||||
pub gsbase: usize,
|
||||
}
|
||||
|
||||
impl UserContext {
|
||||
/// Get number of syscall.
|
||||
pub fn get_syscall_num(&self) -> usize {
|
||||
self.general.rax
|
||||
}
|
||||
|
||||
/// Get return value of syscall.
|
||||
pub fn get_syscall_ret(&self) -> usize {
|
||||
self.general.rax
|
||||
}
|
||||
|
||||
/// Set return value of syscall.
|
||||
pub fn set_syscall_ret(&mut self, ret: usize) {
|
||||
self.general.rax = ret;
|
||||
}
|
||||
|
||||
/// Get syscall args.
|
||||
pub fn get_syscall_args(&self) -> [usize; 6] {
|
||||
[
|
||||
self.general.rdi,
|
||||
self.general.rsi,
|
||||
self.general.rdx,
|
||||
self.general.r10,
|
||||
self.general.r8,
|
||||
self.general.r9,
|
||||
]
|
||||
}
|
||||
|
||||
/// Set instruction pointer.
|
||||
pub fn set_ip(&mut self, ip: usize) {
|
||||
self.general.rip = ip;
|
||||
}
|
||||
|
||||
/// Set stack pointer.
|
||||
pub fn set_sp(&mut self, sp: usize) {
|
||||
self.general.rsp = sp;
|
||||
}
|
||||
|
||||
/// Get stack pointer.
|
||||
pub fn get_sp(&self) -> usize {
|
||||
self.general.rsp
|
||||
}
|
||||
|
||||
/// Set thread-local storage pointer.
|
||||
pub fn set_tls(&mut self, tls: usize) {
|
||||
self.general.fsbase = tls;
|
||||
}
|
||||
pub(super) struct RawUserContext {
|
||||
pub(super) general: GeneralRegs,
|
||||
pub(super) trap_num: usize,
|
||||
pub(super) error_code: usize,
|
||||
}
|
||||
|
||||
/// Returns true if this function is called within the context of an IRQ handler
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ use x86_64::{
|
|||
VirtAddr,
|
||||
};
|
||||
|
||||
use super::UserContext;
|
||||
use super::RawUserContext;
|
||||
|
||||
global_asm!(
|
||||
include_str!("syscall.S"),
|
||||
|
|
@ -80,11 +80,11 @@ pub(super) unsafe fn init() {
|
|||
|
||||
extern "sysv64" {
|
||||
fn syscall_entry();
|
||||
fn syscall_return(regs: &mut UserContext);
|
||||
fn syscall_return(regs: &mut RawUserContext);
|
||||
}
|
||||
|
||||
impl UserContext {
|
||||
/// Go to user space with the context, and come back when a trap occurs.
|
||||
impl RawUserContext {
|
||||
/// Goes to user space with the context, and comes back when a trap occurs.
|
||||
///
|
||||
/// On return, the context will be reset to the status before the trap.
|
||||
/// Trap reason and error code will be placed at `trap_num` and `error_code`.
|
||||
|
|
@ -93,26 +93,7 @@ impl UserContext {
|
|||
///
|
||||
/// If `trap_num` is `0x100`, it will go user by `sysret` (`rcx` and `r11` are dropped),
|
||||
/// otherwise it will use `iret`.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// use trapframe::{UserContext, GeneralRegs};
|
||||
///
|
||||
/// // init user space context
|
||||
/// let mut context = UserContext {
|
||||
/// general: GeneralRegs {
|
||||
/// rip: 0x1000,
|
||||
/// rsp: 0x10000,
|
||||
/// ..Default::default()
|
||||
/// },
|
||||
/// ..Default::default()
|
||||
/// };
|
||||
/// // go to user
|
||||
/// context.run();
|
||||
/// // back from user
|
||||
/// println!("back from user: {:#x?}", context);
|
||||
/// ```
|
||||
pub fn run(&mut self) {
|
||||
pub(in crate::arch) fn run(&mut self) {
|
||||
unsafe {
|
||||
syscall_return(self);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue