mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 15:26:47 +00:00
支持syscall快速系统调用指令 (#417)
* 支持syscall快速系统调用指令 --------- Co-authored-by: LoGin <longjin@DragonOS.org>
This commit is contained in:
parent
2f6f547ae0
commit
1603395155
2
.gitignore
vendored
2
.gitignore
vendored
@ -18,4 +18,4 @@ cppcheck.xml
|
||||
/target/
|
||||
Cargo.lock
|
||||
.cache
|
||||
compile_commands.json
|
||||
compile_commands.json
|
||||
|
@ -1,6 +1,8 @@
|
||||
use crate::time::TimeArch;
|
||||
|
||||
use super::{driver::tsc::TSCManager, setup::setup_arch, CurrentTimeArch};
|
||||
use super::{
|
||||
driver::tsc::TSCManager, setup::setup_arch, syscall::init_syscall_64, CurrentTimeArch,
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn rs_setup_arch() -> i32 {
|
||||
@ -19,3 +21,9 @@ unsafe extern "C" fn rs_get_cycles() -> u64 {
|
||||
unsafe extern "C" fn rs_tsc_get_cpu_khz() -> u64 {
|
||||
return TSCManager::cpu_khz();
|
||||
}
|
||||
|
||||
/// syscall指令初始化
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn rs_init_syscall_64() {
|
||||
init_syscall_64();
|
||||
}
|
||||
|
@ -374,13 +374,13 @@ pub struct X86_64SignalArch;
|
||||
|
||||
impl SignalArch for X86_64SignalArch {
|
||||
unsafe fn do_signal(frame: &mut TrapFrame) {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let siginfo = pcb.try_siginfo(5);
|
||||
|
||||
// 检查sigpending是否为0
|
||||
if ProcessManager::current_pcb()
|
||||
.sig_info()
|
||||
.sig_pending()
|
||||
.signal()
|
||||
.bits()
|
||||
== 0
|
||||
if siginfo
|
||||
.map(|s| s.sig_pending().signal().bits() == 0)
|
||||
.unwrap_or(true)
|
||||
|| !frame.from_user()
|
||||
{
|
||||
// 若没有正在等待处理的信号,或者将要返回到的是内核态,则启用中断,然后返回
|
||||
|
@ -37,16 +37,13 @@ use self::{
|
||||
table::{switch_fs_and_gs, KERNEL_DS, USER_DS},
|
||||
};
|
||||
|
||||
use super::{fpu::FpState, interrupt::TrapFrame, CurrentIrqArch};
|
||||
use super::{fpu::FpState, interrupt::TrapFrame, syscall::X86_64GSData, CurrentIrqArch};
|
||||
|
||||
mod c_adapter;
|
||||
pub mod kthread;
|
||||
pub mod syscall;
|
||||
pub mod table;
|
||||
|
||||
pub const IA32_FS_BASE: u32 = 0xC000_0100;
|
||||
pub const IA32_GS_BASE: u32 = 0xC000_0101;
|
||||
|
||||
extern "C" {
|
||||
/// 从中断返回
|
||||
fn ret_from_intr();
|
||||
@ -66,7 +63,7 @@ static BSP_IDLE_STACK_SPACE: InitProcUnion = InitProcUnion {
|
||||
};
|
||||
|
||||
/// PCB中与架构相关的信息
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub struct ArchPCBInfo {
|
||||
rflags: usize,
|
||||
@ -81,9 +78,10 @@ pub struct ArchPCBInfo {
|
||||
cr2: usize,
|
||||
fsbase: usize,
|
||||
gsbase: usize,
|
||||
fs: u16,
|
||||
gs: u16,
|
||||
|
||||
fs: SegmentSelector,
|
||||
gs: SegmentSelector,
|
||||
/// 存储PCB系统调用栈以及在syscall过程中暂存用户态rsp的结构体
|
||||
gsdata: X86_64GSData,
|
||||
/// 浮点寄存器的状态
|
||||
fp_state: Option<FpState>,
|
||||
}
|
||||
@ -99,7 +97,7 @@ impl ArchPCBInfo {
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 返回一个新的ArchPCBInfo
|
||||
pub fn new(kstack: Option<&KernelStack>) -> Self {
|
||||
pub fn new(kstack: &KernelStack) -> Self {
|
||||
let mut r = Self {
|
||||
rflags: 0,
|
||||
rbx: 0,
|
||||
@ -113,16 +111,17 @@ impl ArchPCBInfo {
|
||||
cr2: 0,
|
||||
fsbase: 0,
|
||||
gsbase: 0,
|
||||
fs: KERNEL_DS.bits(),
|
||||
gs: KERNEL_DS.bits(),
|
||||
gsdata: X86_64GSData {
|
||||
kaddr: VirtAddr::new(0),
|
||||
uaddr: VirtAddr::new(0),
|
||||
},
|
||||
fs: KERNEL_DS,
|
||||
gs: KERNEL_DS,
|
||||
fp_state: None,
|
||||
};
|
||||
|
||||
if kstack.is_some() {
|
||||
let kstack = kstack.unwrap();
|
||||
r.rsp = kstack.stack_max_address().data();
|
||||
r.rbp = kstack.stack_max_address().data();
|
||||
}
|
||||
r.rsp = kstack.stack_max_address().data() - 8;
|
||||
r.rbp = kstack.stack_max_address().data();
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -184,7 +183,7 @@ impl ArchPCBInfo {
|
||||
if x86::controlregs::cr4().contains(Cr4::CR4_ENABLE_FSGSBASE) {
|
||||
self.fsbase = x86::current::segmentation::rdfsbase() as usize;
|
||||
} else {
|
||||
self.fsbase = x86::msr::rdmsr(IA32_FS_BASE) as usize;
|
||||
self.fsbase = x86::msr::rdmsr(x86::msr::IA32_FS_BASE) as usize;
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,7 +191,7 @@ impl ArchPCBInfo {
|
||||
if x86::controlregs::cr4().contains(Cr4::CR4_ENABLE_FSGSBASE) {
|
||||
self.gsbase = x86::current::segmentation::rdgsbase() as usize;
|
||||
} else {
|
||||
self.gsbase = x86::msr::rdmsr(IA32_GS_BASE) as usize;
|
||||
self.gsbase = x86::msr::rdmsr(x86::msr::IA32_GS_BASE) as usize;
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,7 +199,7 @@ impl ArchPCBInfo {
|
||||
if x86::controlregs::cr4().contains(Cr4::CR4_ENABLE_FSGSBASE) {
|
||||
x86::current::segmentation::wrfsbase(self.fsbase as u64);
|
||||
} else {
|
||||
x86::msr::wrmsr(IA32_FS_BASE, self.fsbase as u64);
|
||||
x86::msr::wrmsr(x86::msr::IA32_FS_BASE, self.fsbase as u64);
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,10 +207,23 @@ impl ArchPCBInfo {
|
||||
if x86::controlregs::cr4().contains(Cr4::CR4_ENABLE_FSGSBASE) {
|
||||
x86::current::segmentation::wrgsbase(self.gsbase as u64);
|
||||
} else {
|
||||
x86::msr::wrmsr(IA32_GS_BASE, self.gsbase as u64);
|
||||
x86::msr::wrmsr(x86::msr::IA32_GS_BASE, self.gsbase as u64);
|
||||
}
|
||||
}
|
||||
|
||||
/// 将gsdata写入KernelGsbase寄存器
|
||||
pub unsafe fn store_kernel_gsbase(&self) {
|
||||
x86::msr::wrmsr(
|
||||
x86::msr::IA32_KERNEL_GSBASE,
|
||||
&self.gsdata as *const X86_64GSData as u64,
|
||||
);
|
||||
}
|
||||
|
||||
/// ### 初始化系统调用栈,不得与PCB内核栈冲突(即传入的应该是一个新的栈,避免栈损坏)
|
||||
pub fn init_syscall_stack(&mut self, stack: &KernelStack) {
|
||||
self.gsdata.set_kstack(stack.stack_max_address() - 8);
|
||||
}
|
||||
|
||||
pub fn fsbase(&self) -> usize {
|
||||
self.fsbase
|
||||
}
|
||||
@ -227,6 +239,35 @@ impl ArchPCBInfo {
|
||||
pub fn fp_state_mut(&mut self) -> &mut Option<FpState> {
|
||||
&mut self.fp_state
|
||||
}
|
||||
|
||||
/// ### 克隆ArchPCBInfo,需要注意gsdata也是对应clone的
|
||||
pub fn clone_all(&self) -> Self {
|
||||
Self {
|
||||
rflags: self.rflags,
|
||||
rbx: self.rbx,
|
||||
r12: self.r12,
|
||||
r13: self.r13,
|
||||
r14: self.r14,
|
||||
r15: self.r15,
|
||||
rbp: self.rbp,
|
||||
rsp: self.rsp,
|
||||
rip: self.rip,
|
||||
cr2: self.cr2,
|
||||
fsbase: self.fsbase,
|
||||
gsbase: self.gsbase,
|
||||
fs: self.fs.clone(),
|
||||
gs: self.gs.clone(),
|
||||
gsdata: self.gsdata.clone(),
|
||||
fp_state: self.fp_state,
|
||||
}
|
||||
}
|
||||
|
||||
// ### 从另一个ArchPCBInfo处clone,gsdata会被保留
|
||||
pub fn clone_from(&mut self, from: &Self) {
|
||||
let gsdata = self.gsdata.clone();
|
||||
*self = from.clone_all();
|
||||
self.gsdata = gsdata;
|
||||
}
|
||||
}
|
||||
|
||||
impl ProcessControlBlock {
|
||||
@ -349,8 +390,7 @@ impl ProcessManager {
|
||||
next.arch_info().restore_fsbase();
|
||||
|
||||
// 切换gsbase
|
||||
prev.arch_info().save_gsbase();
|
||||
next.arch_info().restore_gsbase();
|
||||
Self::switch_gsbase(&prev, &next);
|
||||
|
||||
// 切换地址空间
|
||||
let next_addr_space = next.basic().user_vm().as_ref().unwrap().clone();
|
||||
@ -383,6 +423,15 @@ impl ProcessManager {
|
||||
// 正式切换上下文
|
||||
switch_to_inner(prev_arch, next_arch);
|
||||
}
|
||||
|
||||
unsafe fn switch_gsbase(prev: &Arc<ProcessControlBlock>, next: &Arc<ProcessControlBlock>) {
|
||||
asm!("swapgs", options(nostack, preserves_flags));
|
||||
prev.arch_info().save_gsbase();
|
||||
next.arch_info().restore_gsbase();
|
||||
// 将下一个进程的kstack写入kernel_gsbase
|
||||
next.arch_info().store_kernel_gsbase();
|
||||
asm!("swapgs", options(nostack, preserves_flags));
|
||||
}
|
||||
}
|
||||
|
||||
/// 保存上下文,然后切换进程,接着jmp到`switch_finish_hook`钩子函数
|
||||
@ -504,12 +553,15 @@ pub unsafe fn arch_switch_to_user(path: String, argv: Vec<String>, envp: Vec<Str
|
||||
let mut arch_guard = current_pcb.arch_info_irqsave();
|
||||
arch_guard.rsp = trap_frame_vaddr.data();
|
||||
|
||||
arch_guard.fs = USER_DS.bits();
|
||||
arch_guard.gs = USER_DS.bits();
|
||||
arch_guard.fs = USER_DS;
|
||||
arch_guard.gs = USER_DS;
|
||||
|
||||
// 将内核gs数据压进cpu
|
||||
arch_guard.store_kernel_gsbase();
|
||||
|
||||
switch_fs_and_gs(
|
||||
SegmentSelector::from_bits_truncate(arch_guard.fs),
|
||||
SegmentSelector::from_bits_truncate(arch_guard.gs),
|
||||
SegmentSelector::from_bits_truncate(arch_guard.fs.bits()),
|
||||
SegmentSelector::from_bits_truncate(arch_guard.gs.bits()),
|
||||
);
|
||||
arch_guard.rip = new_rip.data();
|
||||
|
||||
@ -548,6 +600,7 @@ unsafe extern "sysv64" fn ready_to_switch_to_user(
|
||||
) -> ! {
|
||||
*(trapframe_vaddr as *mut TrapFrame) = trap_frame;
|
||||
asm!(
|
||||
"swapgs",
|
||||
"mov rsp, {trapframe_vaddr}",
|
||||
"push {new_rip}",
|
||||
"ret",
|
||||
|
@ -10,10 +10,11 @@ use crate::{
|
||||
pub const KERNEL_CS: SegmentSelector = SegmentSelector::new(1, Ring::Ring0);
|
||||
/// kernel data segment selector
|
||||
pub const KERNEL_DS: SegmentSelector = SegmentSelector::new(2, Ring::Ring0);
|
||||
/// user code segment selector
|
||||
pub const USER_CS: SegmentSelector = SegmentSelector::new(5, Ring::Ring3);
|
||||
/// user data segment selector
|
||||
pub const USER_DS: SegmentSelector = SegmentSelector::new(6, Ring::Ring3);
|
||||
pub const USER_DS: SegmentSelector = SegmentSelector::new(5, Ring::Ring3);
|
||||
/// user code segment selector
|
||||
/// 如果改这里,记得改syscall_64里面写死的常量
|
||||
pub const USER_CS: SegmentSelector = SegmentSelector::new(6, Ring::Ring3);
|
||||
|
||||
static mut TSS_MANAGER: TSSManager = TSSManager::new();
|
||||
|
||||
|
@ -1,30 +1,59 @@
|
||||
use core::ffi::c_void;
|
||||
|
||||
use alloc::string::String;
|
||||
|
||||
use crate::{
|
||||
arch::ipc::signal::X86_64SignalArch,
|
||||
arch::{ipc::signal::X86_64SignalArch, CurrentIrqArch},
|
||||
exception::InterruptArch,
|
||||
include::bindings::bindings::set_system_trap_gate,
|
||||
ipc::signal_types::SignalArch,
|
||||
libs::align::SafeForZero,
|
||||
mm::VirtAddr,
|
||||
syscall::{Syscall, SystemError, SYS_RT_SIGRETURN},
|
||||
};
|
||||
use alloc::string::String;
|
||||
|
||||
use super::{interrupt::TrapFrame, mm::barrier::mfence};
|
||||
|
||||
/// ### 存储PCB系统调用栈以及在syscall过程中暂存用户态rsp的结构体
|
||||
///
|
||||
/// 在syscall指令中将会从该结构体中读取系统调用栈和暂存rsp,
|
||||
/// 使用`gsbase`寄存器实现,后续如果需要使用gsbase寄存器,需要相应设置正确的偏移量
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub(super) struct X86_64GSData {
|
||||
pub(super) kaddr: VirtAddr,
|
||||
pub(super) uaddr: VirtAddr,
|
||||
}
|
||||
|
||||
impl X86_64GSData {
|
||||
/// ### 设置系统调用栈,将会在下一个调度后写入KernelGsbase
|
||||
pub fn set_kstack(&mut self, kstack: VirtAddr) {
|
||||
self.kaddr = kstack;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl SafeForZero for X86_64GSData {}
|
||||
|
||||
extern "C" {
|
||||
fn syscall_int();
|
||||
fn syscall_64();
|
||||
}
|
||||
|
||||
macro_rules! syscall_return {
|
||||
($val:expr, $regs:expr) => {{
|
||||
let ret = $val;
|
||||
$regs.rax = ret as u64;
|
||||
unsafe {
|
||||
CurrentIrqArch::interrupt_disable();
|
||||
}
|
||||
return;
|
||||
}};
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn syscall_handler(frame: &mut TrapFrame) -> () {
|
||||
pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) -> () {
|
||||
unsafe {
|
||||
CurrentIrqArch::interrupt_enable();
|
||||
}
|
||||
let syscall_num = frame.rax as usize;
|
||||
let args = [
|
||||
frame.rdi as usize,
|
||||
@ -54,6 +83,7 @@ pub extern "C" fn syscall_handler(frame: &mut TrapFrame) -> () {
|
||||
pub fn arch_syscall_init() -> Result<(), SystemError> {
|
||||
// kinfo!("arch_syscall_init\n");
|
||||
unsafe { set_system_trap_gate(0x80, 0, syscall_int as *mut c_void) }; // 系统调用门
|
||||
unsafe { init_syscall_64() };
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@ -69,3 +99,20 @@ pub extern "C" fn rs_exec_init_process(frame: &mut TrapFrame) -> usize {
|
||||
// kdebug!("rs_exec_init_process: r: {:?}\n", r);
|
||||
return r.map(|_| 0).unwrap_or_else(|e| e.to_posix_errno() as usize);
|
||||
}
|
||||
|
||||
/// syscall指令初始化函数
|
||||
pub(super) unsafe fn init_syscall_64() {
|
||||
let mut efer = x86::msr::rdmsr(x86::msr::IA32_EFER);
|
||||
efer |= 0x1;
|
||||
x86::msr::wrmsr(x86::msr::IA32_EFER, efer);
|
||||
|
||||
let syscall_base = (1 as u16) << 3;
|
||||
let sysret_base = ((4 as u16) << 3) | 3;
|
||||
let high = (u32::from(sysret_base) << 16) | u32::from(syscall_base);
|
||||
// 初始化STAR寄存器
|
||||
x86::msr::wrmsr(x86::msr::IA32_STAR, u64::from(high) << 32);
|
||||
|
||||
// 初始化LSTAR,该寄存器存储syscall指令入口
|
||||
x86::msr::wrmsr(x86::msr::IA32_LSTAR, syscall_64 as u64);
|
||||
x86::msr::wrmsr(x86::msr::IA32_FMASK, 0xfffffffe);
|
||||
}
|
||||
|
@ -412,6 +412,10 @@ int apic_init()
|
||||
*/
|
||||
void do_IRQ(struct pt_regs *rsp, ul number)
|
||||
{
|
||||
if((rsp->cs & 0x3) == 3)
|
||||
{
|
||||
asm volatile("swapgs":::"memory");
|
||||
}
|
||||
if (number < 0x80 && number >= 32) // 以0x80为界限,低于0x80的是外部中断控制器,高于0x80的是Local APIC
|
||||
{
|
||||
// ==========外部中断控制器========
|
||||
|
@ -69,6 +69,21 @@ ENTRY(ret_from_intr)
|
||||
movq %rsp, %rdi
|
||||
callq do_signal
|
||||
|
||||
|
||||
__entry_ret_from_intr_before_gs_check_2:
|
||||
push %rcx
|
||||
addq $8, %rsp
|
||||
movq CS(%rsp), %rcx
|
||||
subq $8, %rsp
|
||||
andq $0x3, %rcx
|
||||
cmpq $0x3, %rcx
|
||||
|
||||
jne __entry_ret_from_intr_after_gs_check_2
|
||||
swapgs
|
||||
|
||||
__entry_ret_from_intr_after_gs_check_2:
|
||||
popq %rcx
|
||||
|
||||
// 恢复寄存器
|
||||
jmp Restore_all
|
||||
|
||||
@ -109,7 +124,20 @@ Err_Code:
|
||||
|
||||
movq %rsp, %rdi // 把栈指针装入rdi,作为函数的第一个的参数
|
||||
|
||||
__entry_err_code_before_gs_check_1:
|
||||
pushq %rcx
|
||||
movq CS(%rdi), %rcx
|
||||
and $0x3, %rcx
|
||||
cmp $0x3, %rcx
|
||||
|
||||
jne __entry_err_code_after_gs_check_1
|
||||
swapgs
|
||||
|
||||
__entry_err_code_after_gs_check_1:
|
||||
popq %rcx
|
||||
|
||||
callq *%rdx //调用服务程序 带*号表示调用的是绝对地址
|
||||
|
||||
jmp ret_from_exception
|
||||
|
||||
|
||||
@ -296,3 +324,87 @@ ENTRY(ignore_int)
|
||||
xchgq %rax, (%rsp) // 把FUNC的地址换入栈中
|
||||
jmp Err_Code
|
||||
|
||||
ENTRY(syscall_64)
|
||||
// 切换用户栈和内核栈
|
||||
swapgs
|
||||
movq %rsp, %gs:0x8
|
||||
movq %gs:0x0, %rsp
|
||||
|
||||
pushq $43 // USER_DS
|
||||
pushq %gs:0x8 // rsp
|
||||
pushq %r11 // RFLAGS
|
||||
pushq $51 // USER_CS
|
||||
pushq %rcx // RIP
|
||||
pushq $0 // error code占位
|
||||
|
||||
pushq %rax
|
||||
leaq syscall_handler(%rip), %rax // FUNC
|
||||
xchgq %rax, (%rsp)
|
||||
|
||||
pushq %rax // rax
|
||||
|
||||
movq %es, %rax
|
||||
pushq %rax // es
|
||||
movq %ds, %rax
|
||||
pushq %rax // ds
|
||||
xorq %rax, %rax
|
||||
|
||||
pushq %rbp
|
||||
pushq %rdi
|
||||
pushq %rsi
|
||||
pushq %rdx
|
||||
pushq %rcx
|
||||
pushq %rbx
|
||||
pushq %r8
|
||||
pushq %r9
|
||||
pushq %r10
|
||||
pushq %r11
|
||||
pushq %r12
|
||||
pushq %r13
|
||||
pushq %r14
|
||||
pushq %r15
|
||||
|
||||
cld
|
||||
|
||||
xorq %rsi, %rsi
|
||||
movq FUNC(%rsp), %rdx
|
||||
|
||||
movq %rsp, %rdi // 把栈指针装入rdi,作为函数的第一个的参数
|
||||
|
||||
callq *%rdx //调用服务程序
|
||||
|
||||
cli
|
||||
|
||||
// === 恢复调用现场 ===
|
||||
popq %r15
|
||||
popq %r14
|
||||
popq %r13
|
||||
popq %r12
|
||||
popq %r11
|
||||
popq %r10
|
||||
popq %r9
|
||||
popq %r8
|
||||
popq %rbx
|
||||
popq %rcx
|
||||
popq %rdx
|
||||
popq %rsi
|
||||
popq %rdi
|
||||
popq %rbp
|
||||
|
||||
popq %rax // 不允许直接pop到ds
|
||||
movq %rax, %ds
|
||||
|
||||
popq %rax
|
||||
movq %rax, %es
|
||||
|
||||
popq %rax
|
||||
addq $0x10, %rsp // 弹出变量FUNC和errcode
|
||||
|
||||
popq %rcx // pop rip到rcx
|
||||
|
||||
addq $0x8, %rsp // 弹出cs
|
||||
popq %r11 // pop rflags到r11
|
||||
popq %rsp // Restore rsp
|
||||
|
||||
swapgs
|
||||
sysretq
|
||||
|
@ -515,8 +515,8 @@ GDT_Table:
|
||||
.quad 0x0000920000000000 // 2 内核64位数据段描述符 0x10
|
||||
.quad 0x0000000000000000 // 3 用户32位代码段描述符 0x18
|
||||
.quad 0x0000000000000000 // 4 用户32位数据段描述符 0x20
|
||||
.quad 0x0020f80000000000 // 5 用户64位代码段描述符 0x28
|
||||
.quad 0x0000f20000000000 // 6 用户64位数据段描述符 0x30
|
||||
.quad 0x00cff3000000ffff // 5 用户64位数据段描述符 0x28
|
||||
.quad 0x00affb000000ffff // 6 用户64位代码段描述符 0x30
|
||||
.quad 0x00cf9a000000ffff // 7 内核32位代码段描述符 0x38
|
||||
.quad 0x00cf92000000ffff // 8 内核32位数据段描述符 0x40
|
||||
.fill 100, 8, 0 // 10-11 TSS(跳过了第9段) 重复十次填充8字节的空间,赋值为0 长模式下,每个TSS长度为128bit
|
||||
|
@ -339,7 +339,9 @@ impl ProcessManager {
|
||||
// TODO: 克隆前应该锁信号处理,等待克隆完成后再处理
|
||||
|
||||
// 克隆架构相关
|
||||
*pcb.arch_info() = current_pcb.arch_info_irqsave().clone();
|
||||
let guard = current_pcb.arch_info_irqsave();
|
||||
pcb.arch_info().clone_from(&guard);
|
||||
drop(guard);
|
||||
|
||||
// 为内核线程设置WorkerPrivate
|
||||
if current_pcb.flags().contains(ProcessFlags::KTHREAD) {
|
||||
|
@ -510,6 +510,9 @@ pub struct ProcessControlBlock {
|
||||
/// 进程的内核栈
|
||||
kernel_stack: RwLock<KernelStack>,
|
||||
|
||||
/// 系统调用栈
|
||||
syscall_stack: RwLock<KernelStack>,
|
||||
|
||||
/// 与调度相关的信息
|
||||
sched_info: RwLock<ProcessSchedulerInfo>,
|
||||
/// 与处理器架构相关的信息
|
||||
@ -571,7 +574,7 @@ impl ProcessControlBlock {
|
||||
let flags = SpinLock::new(ProcessFlags::empty());
|
||||
|
||||
let sched_info = ProcessSchedulerInfo::new(None);
|
||||
let arch_info = SpinLock::new(ArchPCBInfo::new(Some(&kstack)));
|
||||
let arch_info = SpinLock::new(ArchPCBInfo::new(&kstack));
|
||||
|
||||
let ppcb: Weak<ProcessControlBlock> = ProcessManager::find(ppid)
|
||||
.map(|p| Arc::downgrade(&p))
|
||||
@ -583,6 +586,7 @@ impl ProcessControlBlock {
|
||||
preempt_count,
|
||||
flags,
|
||||
kernel_stack: RwLock::new(kstack),
|
||||
syscall_stack: RwLock::new(KernelStack::new().unwrap()),
|
||||
worker_private: SpinLock::new(None),
|
||||
sched_info,
|
||||
arch_info,
|
||||
@ -594,11 +598,21 @@ impl ProcessControlBlock {
|
||||
thread: RwLock::new(ThreadInfo::new()),
|
||||
};
|
||||
|
||||
// 初始化系统调用栈
|
||||
pcb.arch_info
|
||||
.lock()
|
||||
.init_syscall_stack(&pcb.syscall_stack.read());
|
||||
|
||||
let pcb = Arc::new(pcb);
|
||||
|
||||
// 设置进程的arc指针到内核栈的最低地址处
|
||||
// 设置进程的arc指针到内核栈和系统调用栈的最低地址处
|
||||
unsafe {
|
||||
pcb.kernel_stack
|
||||
.write()
|
||||
.set_pcb(Arc::downgrade(&pcb))
|
||||
.unwrap();
|
||||
|
||||
pcb.syscall_stack
|
||||
.write()
|
||||
.set_pcb(Arc::downgrade(&pcb))
|
||||
.unwrap()
|
||||
@ -788,6 +802,16 @@ impl ProcessControlBlock {
|
||||
self.sig_info.read()
|
||||
}
|
||||
|
||||
pub fn try_siginfo(&self, times: u8) -> Option<RwLockReadGuard<ProcessSignalInfo>> {
|
||||
for _ in 0..times {
|
||||
if let Some(r) = self.sig_info.try_read() {
|
||||
return Some(r);
|
||||
}
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
pub fn sig_info_mut(&self) -> RwLockWriteGuard<ProcessSignalInfo> {
|
||||
self.sig_info.write()
|
||||
}
|
||||
@ -1026,7 +1050,7 @@ impl ProcessSchedulerInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct KernelStack {
|
||||
stack: Option<AlignedBox<[u8; KernelStack::SIZE], { KernelStack::ALIGN }>>,
|
||||
/// 标记该内核栈是否可以被释放
|
||||
|
@ -10,8 +10,15 @@
|
||||
#include <process/preempt.h>
|
||||
#include <sched/sched.h>
|
||||
#include <driver/acpi/acpi.h>
|
||||
#include "exception/trap.h"
|
||||
#include "ipi.h"
|
||||
|
||||
/* x86-64 specific MSRs */
|
||||
#define MSR_EFER 0xc0000080 /* extended feature register */
|
||||
#define MSR_STAR 0xc0000081 /* legacy mode SYSCALL target */
|
||||
#define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */
|
||||
#define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */
|
||||
|
||||
static void __smp_kick_cpu_handler(uint64_t irq_num, uint64_t param, struct pt_regs *regs);
|
||||
static void __smp__flush_tlb_ipi_handler(uint64_t irq_num, uint64_t param, struct pt_regs *regs);
|
||||
|
||||
@ -25,6 +32,7 @@ int num_cpu_started = 1;
|
||||
|
||||
extern void smp_ap_start();
|
||||
extern uint64_t rs_get_idle_stack_top(uint32_t cpu_id);
|
||||
extern void rs_init_syscall_64();
|
||||
|
||||
// 在head.S中定义的,APU启动时,要加载的页表
|
||||
// 由于内存管理模块初始化的时候,重置了页表,因此我们要把当前的页表传给APU
|
||||
@ -146,8 +154,11 @@ void smp_ap_start_stage2()
|
||||
io_mfence();
|
||||
spin_unlock_no_preempt(&multi_core_starting_lock);
|
||||
|
||||
rs_init_syscall_64();
|
||||
|
||||
apic_timer_ap_core_init();
|
||||
|
||||
|
||||
sti();
|
||||
sched();
|
||||
|
||||
|
@ -424,6 +424,8 @@ pub const SYS_GET_DENTS_64: usize = 217;
|
||||
#[allow(dead_code)]
|
||||
pub const SYS_SET_TID_ADDR: usize = 218;
|
||||
|
||||
pub const SYS_EXIT_GROUP: usize = 231;
|
||||
|
||||
pub const SYS_UNLINK_AT: usize = 263;
|
||||
|
||||
pub const SYS_PIPE: usize = 293;
|
||||
@ -1121,6 +1123,11 @@ impl Syscall {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
SYS_EXIT_GROUP => {
|
||||
kwarn!("SYS_EXIT_GROUP has not yet been implemented");
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
_ => panic!("Unsupported syscall ID: {}", syscall_num),
|
||||
};
|
||||
return r;
|
||||
|
@ -64,7 +64,7 @@ QEMU_DRIVE="id=disk,file=${QEMU_DISK_IMAGE},if=none"
|
||||
# QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -net nic,netdev=nic0 -netdev tap,id=nic0,model=virtio-net-pci,script=qemu/ifup-nat,downscript=qemu/ifdown-nat -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
||||
QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -device virtio-net-pci,vectors=5,netdev=hostnet0,id=net0 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
||||
# E1000E
|
||||
#QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -net nic,model=e1000e,netdev=hostnet0,id=net0 -netdev user,id=hostnet1,hostfwd=tcp::12581-:12581 -device virtio-net-pci,vectors=5,netdev=hostnet1,id=net1 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
||||
# QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -net nic,model=e1000e,netdev=hostnet0,id=net0 -netdev user,id=hostnet1,hostfwd=tcp::12581-:12581 -device virtio-net-pci,vectors=5,netdev=hostnet1,id=net1 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
||||
QEMU_ARGUMENT="-d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot order=d -monitor ${QEMU_MONITOR} -d ${qemu_trace_std} "
|
||||
|
||||
QEMU_ARGUMENT+="-s -S -enable-kvm -cpu ${QEMU_CPU_FEATURES} -rtc ${QEMU_RTC_CLOCK} -serial ${QEMU_SERIAL} -drive ${QEMU_DRIVE} ${QEMU_DEVICES}"
|
||||
|
Loading…
x
Reference in New Issue
Block a user