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