mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-29 16:13:27 +00:00
Change the memory layout of CpuContext
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
d0268309ff
commit
0fbad25503
@ -11,11 +11,11 @@ cfg-if = "1.0"
|
||||
spin = "0.9.4"
|
||||
volatile = { version = "0.4.5", features = ["unstable"] }
|
||||
buddy_system_allocator = "0.9.0"
|
||||
pod = { path = "../pod" }
|
||||
pod = { git = "https://github.com/sdww0/POD", rev = "7fa2ed2" }
|
||||
intrusive-collections = "0.9.5"
|
||||
log = "0.4"
|
||||
lazy_static = { version = "1.0", features = ["spin_no_std"] }
|
||||
trapframe = { git = "https://github.com/sdww0/trapframe-rs", rev = "13e1065" }
|
||||
trapframe = { git = "https://github.com/sdww0/trapframe-rs", rev = "94fc010" }
|
||||
|
||||
limine = { version = "0.1.10", features = ["into-uuid"], optional = true }
|
||||
x86_64 = { version = "0.14.2", optional = true }
|
||||
|
@ -32,135 +32,75 @@ pub fn this_cpu() -> u32 {
|
||||
#[derive(Clone, Default, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct CpuContext {
|
||||
pub(crate) user_context: UserContext,
|
||||
pub fp_regs: FpRegs,
|
||||
pub gp_regs: GpRegs,
|
||||
pub fs_base: u64,
|
||||
pub gs_base: u64,
|
||||
/// trap information, this field is all zero when it is syscall
|
||||
pub trap_information: TrapInformation,
|
||||
}
|
||||
|
||||
impl CpuContext {
|
||||
pub fn set_rax(&mut self, rax: u64) {
|
||||
self.gp_regs.rax = rax;
|
||||
}
|
||||
|
||||
pub fn set_rsp(&mut self, rsp: u64) {
|
||||
self.gp_regs.rsp = rsp;
|
||||
}
|
||||
|
||||
pub fn set_rip(&mut self, rip: u64) {
|
||||
self.gp_regs.rip = rip;
|
||||
}
|
||||
|
||||
pub fn set_fsbase(&mut self, fs_base: u64) {
|
||||
self.fs_base = fs_base;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct TrapInformation {
|
||||
pub cr2: u64,
|
||||
pub id: u64,
|
||||
pub err: u64,
|
||||
pub cr2: usize,
|
||||
pub id: usize,
|
||||
pub err: usize,
|
||||
}
|
||||
|
||||
/// The general-purpose registers of CPU.
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
#[repr(C)]
|
||||
pub struct GpRegs {
|
||||
pub r8: u64,
|
||||
pub r9: u64,
|
||||
pub r10: u64,
|
||||
pub r11: u64,
|
||||
pub r12: u64,
|
||||
pub r13: u64,
|
||||
pub r14: u64,
|
||||
pub r15: u64,
|
||||
pub rdi: u64,
|
||||
pub rsi: u64,
|
||||
pub rbp: u64,
|
||||
pub rbx: u64,
|
||||
pub rdx: u64,
|
||||
pub rax: u64,
|
||||
pub rcx: u64,
|
||||
pub rsp: u64,
|
||||
pub rip: u64,
|
||||
pub rflag: u64,
|
||||
impl CpuContext {
|
||||
pub fn general_regs(&self) -> GeneralRegs {
|
||||
self.user_context.general
|
||||
}
|
||||
|
||||
pub fn set_general_regs(&mut self, general_register: GeneralRegs) {
|
||||
self.user_context.general = general_register;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Pod for GpRegs {}
|
||||
unsafe impl Pod for TrapInformation {}
|
||||
macro_rules! cpu_context_impl_getter_setter {
|
||||
( $( [ $field: ident, $setter_name: ident] ),*) => {
|
||||
impl CpuContext {
|
||||
$(
|
||||
#[inline(always)]
|
||||
pub fn $field(&self) -> usize {
|
||||
self.user_context.general.$field
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn $setter_name(&mut self, $field: usize) {
|
||||
self.user_context.general.$field = $field;
|
||||
}
|
||||
)*
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
cpu_context_impl_getter_setter!(
|
||||
[rax, set_rax],
|
||||
[rbx, set_rbx],
|
||||
[rcx, set_rcx],
|
||||
[rdx, set_rdx],
|
||||
[rsi, set_rsi],
|
||||
[rdi, set_rdi],
|
||||
[rbp, set_rbp],
|
||||
[rsp, set_rsp],
|
||||
[r8, set_r8],
|
||||
[r9, set_r9],
|
||||
[r10, set_r10],
|
||||
[r11, set_r11],
|
||||
[r12, set_r12],
|
||||
[r13, set_r13],
|
||||
[r14, set_r14],
|
||||
[r15, set_r15],
|
||||
[rip, set_rip],
|
||||
[rflags, set_rflags],
|
||||
[fsbase, set_fsbase],
|
||||
[gsbase, set_gsbase]
|
||||
);
|
||||
|
||||
unsafe impl Pod for CpuContext {}
|
||||
unsafe impl Pod for TrapInformation {}
|
||||
unsafe impl Pod for FpRegs {}
|
||||
|
||||
impl From<UserContext> for CpuContext {
|
||||
fn from(value: UserContext) -> Self {
|
||||
Self {
|
||||
gp_regs: GpRegs {
|
||||
r8: value.general.r8 as u64,
|
||||
r9: value.general.r9 as u64,
|
||||
r10: value.general.r10 as u64,
|
||||
r11: value.general.r11 as u64,
|
||||
r12: value.general.r12 as u64,
|
||||
r13: value.general.r13 as u64,
|
||||
r14: value.general.r14 as u64,
|
||||
r15: value.general.r15 as u64,
|
||||
rdi: value.general.rdi as u64,
|
||||
rsi: value.general.rsi as u64,
|
||||
rbp: value.general.rbp as u64,
|
||||
rbx: value.general.rbx as u64,
|
||||
rdx: value.general.rdx as u64,
|
||||
rax: value.general.rax as u64,
|
||||
rcx: value.general.rcx as u64,
|
||||
rsp: value.general.rsp as u64,
|
||||
rip: value.general.rip as u64,
|
||||
rflag: value.general.rflags as u64,
|
||||
},
|
||||
fs_base: value.general.fsbase as u64,
|
||||
fp_regs: FpRegs::default(),
|
||||
trap_information: TrapInformation {
|
||||
cr2: x86_64::registers::control::Cr2::read_raw(),
|
||||
id: value.trap_num as u64,
|
||||
err: value.error_code as u64,
|
||||
},
|
||||
gs_base: value.general.gsbase as u64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<UserContext> for CpuContext {
|
||||
fn into(self) -> UserContext {
|
||||
UserContext {
|
||||
trap_num: self.trap_information.id as usize,
|
||||
error_code: self.trap_information.err as usize,
|
||||
general: GeneralRegs {
|
||||
rax: self.gp_regs.rax as usize,
|
||||
rbx: self.gp_regs.rbx as usize,
|
||||
rcx: self.gp_regs.rcx as usize,
|
||||
rdx: self.gp_regs.rdx as usize,
|
||||
rsi: self.gp_regs.rsi as usize,
|
||||
rdi: self.gp_regs.rdi as usize,
|
||||
rbp: self.gp_regs.rbp as usize,
|
||||
rsp: self.gp_regs.rsp as usize,
|
||||
r8: self.gp_regs.r8 as usize,
|
||||
r9: self.gp_regs.r9 as usize,
|
||||
r10: self.gp_regs.r10 as usize,
|
||||
r11: self.gp_regs.r11 as usize,
|
||||
r12: self.gp_regs.r12 as usize,
|
||||
r13: self.gp_regs.r13 as usize,
|
||||
r14: self.gp_regs.r14 as usize,
|
||||
r15: self.gp_regs.r15 as usize,
|
||||
rip: self.gp_regs.rip as usize,
|
||||
rflags: self.gp_regs.rflag as usize,
|
||||
fsbase: self.fs_base as usize,
|
||||
gsbase: self.gs_base as usize,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The floating-point state of CPU.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
|
@ -5,8 +5,8 @@ mod kernel;
|
||||
pub(crate) mod mm;
|
||||
pub(crate) mod timer;
|
||||
|
||||
use core::fmt::Write;
|
||||
use alloc::fmt;
|
||||
use core::fmt::Write;
|
||||
use log::{debug, info};
|
||||
use trapframe::TrapFrame;
|
||||
use x86_64::registers::{
|
||||
@ -19,7 +19,7 @@ use crate::{
|
||||
user::{UserEvent, UserMode, UserModeExecute},
|
||||
};
|
||||
|
||||
use self::cpu::CpuContext;
|
||||
use self::cpu::TrapInformation;
|
||||
|
||||
pub(crate) fn before_all_init() {
|
||||
enable_common_cpu_features();
|
||||
@ -54,62 +54,76 @@ impl<'a> UserModeExecute for UserMode<'a> {
|
||||
}
|
||||
if !self.executed {
|
||||
self.context = self.user_space.cpu_ctx;
|
||||
if self.context.gp_regs.rflag == 0 {
|
||||
self.context.gp_regs.rflag = (RFlags::INTERRUPT_FLAG | RFlags::ID).bits() | 0x2;
|
||||
if self.context.user_context.general.rflags == 0 {
|
||||
self.context.user_context.general.rflags =
|
||||
((RFlags::INTERRUPT_FLAG | RFlags::ID).bits() | 0x2) as usize;
|
||||
}
|
||||
// write fsbase
|
||||
unsafe {
|
||||
FS::write_base(x86_64::VirtAddr::new(self.user_space.cpu_ctx.fs_base));
|
||||
FS::write_base(x86_64::VirtAddr::new(
|
||||
self.context.user_context.general.fsbase as u64,
|
||||
));
|
||||
}
|
||||
let fp_regs = self.user_space.cpu_ctx.fp_regs;
|
||||
let fp_regs = self.context.fp_regs;
|
||||
if fp_regs.is_valid() {
|
||||
fp_regs.restore();
|
||||
}
|
||||
self.executed = true;
|
||||
} else {
|
||||
// write fsbase
|
||||
if FS::read_base().as_u64() != self.context.fs_base {
|
||||
debug!("write fsbase: 0x{:x}", self.context.fs_base);
|
||||
if FS::read_base().as_u64() != self.context.user_context.general.fsbase as u64 {
|
||||
debug!(
|
||||
"write fsbase: 0x{:x}",
|
||||
self.context.user_context.general.fsbase
|
||||
);
|
||||
unsafe {
|
||||
FS::write_base(x86_64::VirtAddr::new(self.context.fs_base));
|
||||
FS::write_base(x86_64::VirtAddr::new(
|
||||
self.context.user_context.general.fsbase as u64,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
self.user_context = self.context.into();
|
||||
self.user_context.run();
|
||||
self.context.user_context.run();
|
||||
let mut trap_frame;
|
||||
while self.user_context.trap_num >= 0x20 && self.user_context.trap_num < 0x100 {
|
||||
while self.context.user_context.trap_num >= 0x20
|
||||
&& self.context.user_context.trap_num < 0x100
|
||||
{
|
||||
trap_frame = TrapFrame {
|
||||
rax: self.user_context.general.rax,
|
||||
rbx: self.user_context.general.rbx,
|
||||
rcx: self.user_context.general.rcx,
|
||||
rdx: self.user_context.general.rdx,
|
||||
rsi: self.user_context.general.rsi,
|
||||
rdi: self.user_context.general.rdi,
|
||||
rbp: self.user_context.general.rbp,
|
||||
rsp: self.user_context.general.rsp,
|
||||
r8: self.user_context.general.r8,
|
||||
r9: self.user_context.general.r9,
|
||||
r10: self.user_context.general.r10,
|
||||
r11: self.user_context.general.r11,
|
||||
r12: self.user_context.general.r12,
|
||||
r13: self.user_context.general.r13,
|
||||
r14: self.user_context.general.r14,
|
||||
r15: self.user_context.general.r15,
|
||||
rax: self.context.user_context.general.rax,
|
||||
rbx: self.context.user_context.general.rbx,
|
||||
rcx: self.context.user_context.general.rcx,
|
||||
rdx: self.context.user_context.general.rdx,
|
||||
rsi: self.context.user_context.general.rsi,
|
||||
rdi: self.context.user_context.general.rdi,
|
||||
rbp: self.context.user_context.general.rbp,
|
||||
rsp: self.context.user_context.general.rsp,
|
||||
r8: self.context.user_context.general.r8,
|
||||
r9: self.context.user_context.general.r9,
|
||||
r10: self.context.user_context.general.r10,
|
||||
r11: self.context.user_context.general.r11,
|
||||
r12: self.context.user_context.general.r12,
|
||||
r13: self.context.user_context.general.r13,
|
||||
r14: self.context.user_context.general.r14,
|
||||
r15: self.context.user_context.general.r15,
|
||||
_pad: 0,
|
||||
trap_num: self.user_context.trap_num,
|
||||
error_code: self.user_context.error_code,
|
||||
rip: self.user_context.general.rip,
|
||||
trap_num: self.context.user_context.trap_num,
|
||||
error_code: self.context.user_context.error_code,
|
||||
rip: self.context.user_context.general.rip,
|
||||
cs: 0,
|
||||
rflags: self.user_context.general.rflags,
|
||||
rflags: self.context.user_context.general.rflags,
|
||||
};
|
||||
call_irq_callback_functions(&mut trap_frame);
|
||||
self.user_context.run();
|
||||
self.context.user_context.run();
|
||||
}
|
||||
// only syscall and irq < 32 will go back
|
||||
x86_64::instructions::interrupts::enable();
|
||||
self.context = CpuContext::from(self.user_context);
|
||||
self.context.fs_base = FS::read_base().as_u64();
|
||||
if self.user_context.trap_num != 0x100 {
|
||||
self.context.user_context.general.fsbase = FS::read_base().as_u64() as usize;
|
||||
if self.context.user_context.trap_num != 0x100 {
|
||||
self.context.trap_information = TrapInformation {
|
||||
cr2: unsafe { x86::controlregs::cr2() },
|
||||
id: self.context.user_context.trap_num,
|
||||
err: self.context.user_context.error_code,
|
||||
};
|
||||
UserEvent::Exception
|
||||
} else {
|
||||
UserEvent::Syscall
|
||||
|
@ -2,21 +2,11 @@
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature="x86_64")]{
|
||||
|
||||
pub use crate::arch::x86::cpu::CpuContext;
|
||||
pub use crate::arch::x86::cpu::TrapInformation;
|
||||
pub use crate::arch::x86::cpu::GpRegs;
|
||||
pub use crate::arch::x86::cpu::FpRegs;
|
||||
|
||||
/// Returns the number of CPUs.
|
||||
pub fn num_cpus() -> u32 {
|
||||
crate::arch::x86::cpu::num_cpus()
|
||||
}
|
||||
|
||||
/// Returns the ID of this CPU.
|
||||
pub fn this_cpu() -> u32 {
|
||||
crate::arch::x86::cpu::this_cpu()
|
||||
}
|
||||
|
||||
pub use crate::arch::x86::cpu::TrapInformation;
|
||||
pub use trapframe::GeneralRegs;
|
||||
pub use crate::arch::x86::cpu::num_cpus;
|
||||
pub use crate::arch::x86::cpu::this_cpu;
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ pub(crate) fn call_irq_callback_functions(f: &mut TrapFrame) {
|
||||
/// This function will determine a trap is a CPU faults.
|
||||
/// We will pass control to jinux-std if the trap is **faults**.
|
||||
pub fn is_cpu_fault(trap_frame: &TrapFrame) -> bool {
|
||||
match trap_frame.trap_num as u64 {
|
||||
match trap_frame.trap_num {
|
||||
DIVIDE_BY_ZERO
|
||||
| DEBUG
|
||||
| BOUND_RANGE_EXCEEDED
|
||||
|
@ -15,7 +15,7 @@ pub(crate) fn init() {
|
||||
macro_rules! define_cpu_exception {
|
||||
( $( $name: ident = $exception_num: expr ),* ) => {
|
||||
$(
|
||||
pub const $name : u64 = $exception_num;
|
||||
pub const $name : usize = $exception_num;
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,6 @@ pub struct UserMode<'a> {
|
||||
current: Arc<Task>,
|
||||
pub(crate) user_space: &'a Arc<UserSpace>,
|
||||
pub(crate) context: CpuContext,
|
||||
pub(crate) user_context: UserContext,
|
||||
pub(crate) executed: bool,
|
||||
}
|
||||
|
||||
@ -107,7 +106,6 @@ impl<'a> UserMode<'a> {
|
||||
user_space,
|
||||
context: CpuContext::default(),
|
||||
executed: false,
|
||||
user_context: UserContext::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,9 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
inventory = {git="https://github.com/sdww0/inventory"}
|
||||
inventory = { git = "https://github.com/sdww0/inventory", rev = "6356dc7" }
|
||||
log = "0.4"
|
||||
component-macro = {path = "../component-macro"}
|
||||
component-macro = { path = "../component-macro" }
|
||||
|
||||
[build-dependencies]
|
||||
json= "0.12.4"
|
||||
json = "0.12.4"
|
||||
|
@ -8,12 +8,12 @@ edition = "2021"
|
||||
[dependencies]
|
||||
bitflags = "1.3"
|
||||
spin = "0.9.4"
|
||||
jinux-frame = {path = "../../../framework/jinux-frame"}
|
||||
jinux-pci = {path="../pci"}
|
||||
jinux-virtio = {path="../virtio"}
|
||||
jinux-util = {path="../../libs/jinux-util"}
|
||||
pod = {path = "../../../framework/pod"}
|
||||
component = {path="../../comp-sys/component"}
|
||||
jinux-frame = { path = "../../../framework/jinux-frame" }
|
||||
jinux-pci = { path = "../pci" }
|
||||
jinux-virtio = { path = "../virtio" }
|
||||
jinux-util = { path = "../../libs/jinux-util" }
|
||||
pod = { git = "https://github.com/sdww0/POD", rev = "7fa2ed2" }
|
||||
component = { path = "../../comp-sys/component" }
|
||||
log = "0.4"
|
||||
|
||||
[features]
|
||||
|
@ -8,12 +8,12 @@ edition = "2021"
|
||||
[dependencies]
|
||||
bitflags = "1.3"
|
||||
spin = "0.9.4"
|
||||
jinux-frame = {path = "../../../framework/jinux-frame"}
|
||||
jinux-pci = {path="../pci"}
|
||||
jinux-virtio = {path="../virtio"}
|
||||
jinux-util = {path="../../libs/jinux-util"}
|
||||
pod = {path = "../../../framework/pod"}
|
||||
component = {path="../../comp-sys/component"}
|
||||
jinux-frame = { path = "../../../framework/jinux-frame" }
|
||||
jinux-pci = { path = "../pci" }
|
||||
jinux-virtio = { path = "../virtio" }
|
||||
jinux-util = { path = "../../libs/jinux-util" }
|
||||
pod = { git = "https://github.com/sdww0/POD", rev = "7fa2ed2" }
|
||||
component = { path = "../../comp-sys/component" }
|
||||
virtio-input-decoder = "0.1.4"
|
||||
log = "0.4"
|
||||
|
||||
|
@ -8,10 +8,10 @@ edition = "2021"
|
||||
[dependencies]
|
||||
bitflags = "1.3"
|
||||
spin = "0.9.4"
|
||||
jinux-frame = {path = "../../../framework/jinux-frame"}
|
||||
jinux-util = {path="../../libs/jinux-util"}
|
||||
pod = {path = "../../../framework/pod"}
|
||||
component = {path="../../comp-sys/component"}
|
||||
jinux-frame = { path = "../../../framework/jinux-frame" }
|
||||
jinux-util = { path = "../../libs/jinux-util" }
|
||||
pod = { git = "https://github.com/sdww0/POD", rev = "7fa2ed2" }
|
||||
component = { path = "../../comp-sys/component" }
|
||||
log = "0.4"
|
||||
|
||||
[dependencies.lazy_static]
|
||||
@ -19,4 +19,3 @@ version = "1.0"
|
||||
features = ["spin_no_std"]
|
||||
|
||||
[features]
|
||||
|
||||
|
@ -8,13 +8,11 @@ edition = "2021"
|
||||
[dependencies]
|
||||
bitflags = "1.3"
|
||||
spin = "0.9.4"
|
||||
jinux-frame = {path = "../../../framework/jinux-frame"}
|
||||
jinux-pci = {path="../pci"}
|
||||
jinux-util = {path="../../libs/jinux-util"}
|
||||
pod = {path = "../../../framework/pod"}
|
||||
component = {path="../../comp-sys/component"}
|
||||
jinux-frame = { path = "../../../framework/jinux-frame" }
|
||||
jinux-pci = { path = "../pci" }
|
||||
jinux-util = { path = "../../libs/jinux-util" }
|
||||
pod = { git = "https://github.com/sdww0/POD", rev = "7fa2ed2" }
|
||||
component = { path = "../../comp-sys/component" }
|
||||
log = "0.4"
|
||||
|
||||
[features]
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
jinux-frame = { path = "../../../framework/jinux-frame" }
|
||||
pod = { path = "../../../framework/pod" }
|
||||
pod = { git = "https://github.com/sdww0/POD", rev = "7fa2ed2" }
|
||||
jinux-input = { path = "../../comps/input" }
|
||||
jinux-block = { path = "../../comps/block" }
|
||||
jinux-time = { path = "../../comps/time" }
|
||||
|
@ -341,11 +341,11 @@ fn clone_cpu_context(
|
||||
debug_assert!(new_sp != 0);
|
||||
}
|
||||
if new_sp != 0 {
|
||||
child_context.set_rsp(new_sp as u64);
|
||||
child_context.set_rsp(new_sp as usize);
|
||||
}
|
||||
if clone_flags.contains(CloneFlags::CLONE_SETTLS) {
|
||||
// x86_64 specific: TLS is the fsbase register
|
||||
child_context.set_fsbase(tls as u64);
|
||||
child_context.set_fsbase(tls as usize);
|
||||
}
|
||||
|
||||
child_context
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
use core::mem;
|
||||
|
||||
use jinux_frame::cpu::GpRegs;
|
||||
use jinux_frame::cpu::GeneralRegs;
|
||||
use jinux_util::{read_union_fields, union_read_ptr::UnionReadPtr};
|
||||
|
||||
use crate::{prelude::*, process::Pid};
|
||||
@ -190,7 +190,7 @@ pub struct mcontext_t {
|
||||
#[derive(Debug, Clone, Copy, Pod, Default)]
|
||||
#[repr(C)]
|
||||
pub struct SignalCpuContext {
|
||||
pub gp_regs: GpRegs,
|
||||
pub gp_regs: GeneralRegs,
|
||||
pub fpregs_on_heap: u64,
|
||||
pub fpregs: Vaddr, // *mut FpRegs,
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ pub fn handle_user_signal(
|
||||
|
||||
// Set up signal stack in user stack,
|
||||
// to avoid corrupting user stack, we minus 128 first.
|
||||
let mut user_rsp = context.gp_regs.rsp;
|
||||
let mut user_rsp = context.gp_regs.rsp() as u64;
|
||||
user_rsp = user_rsp - 128;
|
||||
|
||||
// 1. write siginfo_t
|
||||
@ -144,7 +144,7 @@ pub fn handle_user_signal(
|
||||
user_rsp = alloc_aligned_in_user_stack(user_rsp, mem::size_of::<ucontext_t>(), 16)?;
|
||||
let mut ucontext = ucontext_t::default();
|
||||
ucontext.uc_sigmask = mask.as_u64();
|
||||
ucontext.uc_mcontext.inner.gp_regs = context.gp_regs;
|
||||
ucontext.uc_mcontext.inner.gp_regs = context.general_regs();
|
||||
let mut sig_context = posix_thread.sig_context().lock();
|
||||
if let Some(sig_context_addr) = *sig_context {
|
||||
ucontext.uc_link = sig_context_addr;
|
||||
@ -178,16 +178,16 @@ pub fn handle_user_signal(
|
||||
user_rsp = write_u64_to_user_stack(user_rsp, trampoline_rip)?;
|
||||
}
|
||||
// 4. Set correct register values
|
||||
context.gp_regs.rip = handler_addr as _;
|
||||
context.gp_regs.rsp = user_rsp;
|
||||
context.set_rip(handler_addr as _);
|
||||
context.set_rsp(user_rsp as usize);
|
||||
// parameters of signal handler
|
||||
context.gp_regs.rdi = sig_num.as_u8() as u64; // signal number
|
||||
context.set_rdi(sig_num.as_u8() as usize); // signal number
|
||||
if flags.contains(SigActionFlags::SA_SIGINFO) {
|
||||
context.gp_regs.rsi = siginfo_addr; // siginfo_t* siginfo
|
||||
context.gp_regs.rdx = ucontext_addr; // void* ctx
|
||||
context.set_rsi(siginfo_addr as usize); // siginfo_t* siginfo
|
||||
context.set_rdx(ucontext_addr as usize); // void* ctx
|
||||
} else {
|
||||
context.gp_regs.rsi = 0;
|
||||
context.gp_regs.rdx = 0;
|
||||
context.set_rsi(0);
|
||||
context.set_rdx(0);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -30,13 +30,13 @@ impl FaultSignal {
|
||||
INVALID_OPCODE => (SIGILL, ILL_ILLOPC, None),
|
||||
GENERAL_PROTECTION_FAULT => (SIGBUS, BUS_ADRERR, None),
|
||||
PAGE_FAULT => {
|
||||
const PF_ERR_FLAG_PRESENT: u64 = 1u64 << 0;
|
||||
const PF_ERR_FLAG_PRESENT: usize = 1usize << 0;
|
||||
let code = if trap_info.err & PF_ERR_FLAG_PRESENT != 0 {
|
||||
SEGV_ACCERR
|
||||
} else {
|
||||
SEGV_MAPERR
|
||||
};
|
||||
let addr = Some(trap_info.cr2);
|
||||
let addr = Some(trap_info.cr2 as u64);
|
||||
(SIGSEGV, code, addr)
|
||||
}
|
||||
_ => panic!("Exception cannnot be a signal"),
|
||||
|
@ -42,10 +42,10 @@ pub fn sys_arch_prctl(code: u64, addr: u64, context: &mut CpuContext) -> Result<
|
||||
pub fn do_arch_prctl(code: ArchPrctlCode, addr: u64, context: &mut CpuContext) -> Result<u64> {
|
||||
match code {
|
||||
ArchPrctlCode::ARCH_SET_FS => {
|
||||
context.fs_base = addr;
|
||||
context.set_fsbase(addr as usize);
|
||||
Ok(0)
|
||||
}
|
||||
ArchPrctlCode::ARCH_GET_FS => Ok(context.fs_base),
|
||||
ArchPrctlCode::ARCH_GET_FS => Ok(context.fsbase() as u64),
|
||||
ArchPrctlCode::ARCH_GET_GS | ArchPrctlCode::ARCH_SET_GS => {
|
||||
return_errno_with_message!(Errno::EINVAL, "GS cannot be accessed from the user space")
|
||||
}
|
||||
|
@ -51,14 +51,14 @@ pub fn sys_execve(
|
||||
current.sig_dispositions().lock().inherit();
|
||||
// set cpu context to default
|
||||
let defalut_content = CpuContext::default();
|
||||
context.gp_regs = defalut_content.gp_regs;
|
||||
context.fs_base = defalut_content.fs_base;
|
||||
context.set_general_regs(defalut_content.general_regs());
|
||||
context.set_fsbase(defalut_content.fsbase());
|
||||
context.fp_regs = defalut_content.fp_regs;
|
||||
// set new entry point
|
||||
context.gp_regs.rip = elf_load_info.entry_point() as _;
|
||||
context.set_rip(elf_load_info.entry_point() as _);
|
||||
debug!("entry_point: 0x{:x}", elf_load_info.entry_point());
|
||||
// set new user stack top
|
||||
context.gp_regs.rsp = elf_load_info.user_stack_top() as _;
|
||||
context.set_rsp(elf_load_info.user_stack_top() as _);
|
||||
debug!("user stack top: 0x{:x}", elf_load_info.user_stack_top());
|
||||
Ok(SyscallReturn::NoReturn)
|
||||
}
|
||||
|
@ -249,14 +249,14 @@ pub enum SyscallReturn {
|
||||
|
||||
impl SyscallArgument {
|
||||
fn new_from_context(context: &CpuContext) -> Self {
|
||||
let syscall_number = context.gp_regs.rax;
|
||||
let syscall_number = context.rax() as u64;
|
||||
let mut args = [0u64; 6];
|
||||
args[0] = context.gp_regs.rdi;
|
||||
args[1] = context.gp_regs.rsi;
|
||||
args[2] = context.gp_regs.rdx;
|
||||
args[3] = context.gp_regs.r10;
|
||||
args[4] = context.gp_regs.r8;
|
||||
args[5] = context.gp_regs.r9;
|
||||
args[0] = context.rdi() as u64;
|
||||
args[1] = context.rsi() as u64;
|
||||
args[2] = context.rdx() as u64;
|
||||
args[3] = context.r10() as u64;
|
||||
args[4] = context.r8() as u64;
|
||||
args[5] = context.r9() as u64;
|
||||
Self {
|
||||
syscall_number,
|
||||
args,
|
||||
@ -272,13 +272,13 @@ pub fn handle_syscall(context: &mut CpuContext) {
|
||||
match syscall_return {
|
||||
Ok(return_value) => {
|
||||
if let SyscallReturn::Return(return_value) = return_value {
|
||||
context.set_rax(return_value as u64);
|
||||
context.set_rax(return_value as usize);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
debug!("syscall return error: {:?}", err);
|
||||
let errno = err.error() as i32;
|
||||
context.set_rax((-errno) as u64)
|
||||
context.set_rax((-errno) as usize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ pub fn sys_rt_sigreturn(context: &mut CpuContext) -> Result<SyscallReturn> {
|
||||
// FIXME: This assertion is not always true, if RESTORER flag is not presented.
|
||||
// In this case, we will put restorer code on user stack, then the assertion will fail.
|
||||
// However, for most glibc applications, the restorer codes is provided by glibc and RESTORER flag is set.
|
||||
debug_assert!(sig_context_addr == context.gp_regs.rsp as Vaddr);
|
||||
debug_assert!(sig_context_addr == context.rsp() as Vaddr);
|
||||
|
||||
let ucontext = read_val_from_user::<ucontext_t>(sig_context_addr)?;
|
||||
// Set previous ucontext address
|
||||
@ -29,7 +29,7 @@ pub fn sys_rt_sigreturn(context: &mut CpuContext) -> Result<SyscallReturn> {
|
||||
} else {
|
||||
*sig_context = Some(ucontext.uc_link);
|
||||
};
|
||||
context.gp_regs = ucontext.uc_mcontext.inner.gp_regs;
|
||||
context.set_general_regs(ucontext.uc_mcontext.inner.gp_regs);
|
||||
// unblock sig mask
|
||||
let sig_mask = ucontext.uc_sigmask;
|
||||
posix_thread.sig_mask().lock().unblock(sig_mask);
|
||||
|
@ -24,8 +24,8 @@ pub fn handle_exception(context: &mut CpuContext) {
|
||||
}
|
||||
|
||||
fn handle_page_fault(trap_info: &TrapInformation) {
|
||||
const PAGE_NOT_PRESENT_ERROR_MASK: u64 = 0x1 << 0;
|
||||
const WRITE_ACCESS_MASK: u64 = 0x1 << 1;
|
||||
const PAGE_NOT_PRESENT_ERROR_MASK: usize = 0x1 << 0;
|
||||
const WRITE_ACCESS_MASK: usize = 0x1 << 1;
|
||||
let not_present = trap_info.err & PAGE_NOT_PRESENT_ERROR_MASK == 0;
|
||||
let write = trap_info.err & WRITE_ACCESS_MASK != 0;
|
||||
if not_present || write {
|
||||
|
@ -17,9 +17,9 @@ pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>
|
||||
let cur = Task::current();
|
||||
let user_space = cur.user_space().expect("user task should have user space");
|
||||
let mut user_mode = UserMode::new(user_space);
|
||||
debug!("[Task entry] rip = 0x{:x}", user_space.cpu_ctx.gp_regs.rip);
|
||||
debug!("[Task entry] rsp = 0x{:x}", user_space.cpu_ctx.gp_regs.rsp);
|
||||
debug!("[Task entry] rax = 0x{:x}", user_space.cpu_ctx.gp_regs.rax);
|
||||
debug!("[Task entry] rip = 0x{:x}", user_space.cpu_ctx.rip());
|
||||
debug!("[Task entry] rsp = 0x{:x}", user_space.cpu_ctx.rsp());
|
||||
debug!("[Task entry] rax = 0x{:x}", user_space.cpu_ctx.rax());
|
||||
loop {
|
||||
let user_event = user_mode.execute();
|
||||
let context = user_mode.context_mut();
|
||||
|
@ -7,7 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
jinux-frame = {path = "../../../framework/jinux-frame"}
|
||||
pod = {path = "../../../framework/pod"}
|
||||
pod = { git = "https://github.com/sdww0/POD", rev = "7fa2ed2" }
|
||||
|
||||
[features]
|
||||
|
||||
|
Reference in New Issue
Block a user