Browse Source

支持syscall快速系统调用指令 (#417)

* 支持syscall快速系统调用指令

---------

Co-authored-by: LoGin <[email protected]>
GnoCiYeH 1 year ago
parent
commit
1603395155

+ 1 - 1
.gitignore

@@ -18,4 +18,4 @@ cppcheck.xml
 /target/
 Cargo.lock
 .cache
-compile_commands.json
+compile_commands.json

+ 9 - 1
kernel/src/arch/x86_64/c_adapter.rs

@@ -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();
+}

+ 6 - 6
kernel/src/arch/x86_64/ipc/signal.rs

@@ -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()
         {
             // 若没有正在等待处理的信号,或者将要返回到的是内核态,则启用中断,然后返回

+ 79 - 26
kernel/src/arch/x86_64/process/mod.rs

@@ -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",

+ 4 - 3
kernel/src/arch/x86_64/process/table.rs

@@ -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();
 

+ 51 - 4
kernel/src/arch/x86_64/syscall.rs

@@ -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);
+}

+ 4 - 0
kernel/src/driver/interrupt/apic/apic.c

@@ -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
     {
         // ==========外部中断控制器========

+ 112 - 0
kernel/src/exception/entry.S

@@ -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

+ 2 - 2
kernel/src/head.S

@@ -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

+ 3 - 1
kernel/src/process/fork.rs

@@ -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) {

+ 27 - 3
kernel/src/process/mod.rs

@@ -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 }>>,
     /// 标记该内核栈是否可以被释放

+ 11 - 0
kernel/src/smp/smp.c

@@ -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();
 

+ 7 - 0
kernel/src/syscall/mod.rs

@@ -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;

+ 1 - 1
tools/run-qemu.sh

@@ -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}"