From 1603395155fc166de0ac5f80369526e196526ed2 Mon Sep 17 00:00:00 2001 From: GnoCiYeH Date: Sat, 4 Nov 2023 21:39:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81syscall=E5=BF=AB=E9=80=9F?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E8=B0=83=E7=94=A8=E6=8C=87=E4=BB=A4=20(#417)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 支持syscall快速系统调用指令 --------- Co-authored-by: LoGin --- .gitignore | 2 +- kernel/src/arch/x86_64/c_adapter.rs | 10 ++- kernel/src/arch/x86_64/ipc/signal.rs | 12 +-- kernel/src/arch/x86_64/process/mod.rs | 105 ++++++++++++++++------ kernel/src/arch/x86_64/process/table.rs | 7 +- kernel/src/arch/x86_64/syscall.rs | 55 +++++++++++- kernel/src/driver/interrupt/apic/apic.c | 4 + kernel/src/exception/entry.S | 112 ++++++++++++++++++++++++ kernel/src/head.S | 4 +- kernel/src/process/fork.rs | 4 +- kernel/src/process/mod.rs | 30 ++++++- kernel/src/smp/smp.c | 11 +++ kernel/src/syscall/mod.rs | 7 ++ tools/run-qemu.sh | 2 +- 14 files changed, 317 insertions(+), 48 deletions(-) diff --git a/.gitignore b/.gitignore index 525bef56..b2aeedff 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,4 @@ cppcheck.xml /target/ Cargo.lock .cache -compile_commands.json \ No newline at end of file +compile_commands.json diff --git a/kernel/src/arch/x86_64/c_adapter.rs b/kernel/src/arch/x86_64/c_adapter.rs index f6e30141..d79ae525 100644 --- a/kernel/src/arch/x86_64/c_adapter.rs +++ b/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(); +} diff --git a/kernel/src/arch/x86_64/ipc/signal.rs b/kernel/src/arch/x86_64/ipc/signal.rs index 9ce48b21..df946b40 100644 --- a/kernel/src/arch/x86_64/ipc/signal.rs +++ b/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() { // 若没有正在等待处理的信号,或者将要返回到的是内核态,则启用中断,然后返回 diff --git a/kernel/src/arch/x86_64/process/mod.rs b/kernel/src/arch/x86_64/process/mod.rs index 107ad82f..23c2a955 100644 --- a/kernel/src/arch/x86_64/process/mod.rs +++ b/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, } @@ -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 { &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, next: &Arc) { + 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, envp: Vec ! { *(trapframe_vaddr as *mut TrapFrame) = trap_frame; asm!( + "swapgs", "mov rsp, {trapframe_vaddr}", "push {new_rip}", "ret", diff --git a/kernel/src/arch/x86_64/process/table.rs b/kernel/src/arch/x86_64/process/table.rs index db252cb3..bf5aa716 100644 --- a/kernel/src/arch/x86_64/process/table.rs +++ b/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(); diff --git a/kernel/src/arch/x86_64/syscall.rs b/kernel/src/arch/x86_64/syscall.rs index 54af8be8..966e5873 100644 --- a/kernel/src/arch/x86_64/syscall.rs +++ b/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); +} diff --git a/kernel/src/driver/interrupt/apic/apic.c b/kernel/src/driver/interrupt/apic/apic.c index 09c1f96b..337d331d 100644 --- a/kernel/src/driver/interrupt/apic/apic.c +++ b/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 { // ==========外部中断控制器======== diff --git a/kernel/src/exception/entry.S b/kernel/src/exception/entry.S index 50e8ccbc..734e104d 100644 --- a/kernel/src/exception/entry.S +++ b/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 diff --git a/kernel/src/head.S b/kernel/src/head.S index af906cf0..14962276 100644 --- a/kernel/src/head.S +++ b/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 diff --git a/kernel/src/process/fork.rs b/kernel/src/process/fork.rs index 931eb379..33e4ceb6 100644 --- a/kernel/src/process/fork.rs +++ b/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) { diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index b3bdeddf..7ec0dc7a 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -510,6 +510,9 @@ pub struct ProcessControlBlock { /// 进程的内核栈 kernel_stack: RwLock, + /// 系统调用栈 + syscall_stack: RwLock, + /// 与调度相关的信息 sched_info: RwLock, /// 与处理器架构相关的信息 @@ -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 = 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> { + 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 { self.sig_info.write() } @@ -1026,7 +1050,7 @@ impl ProcessSchedulerInfo { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct KernelStack { stack: Option>, /// 标记该内核栈是否可以被释放 diff --git a/kernel/src/smp/smp.c b/kernel/src/smp/smp.c index 3ef8e959..4da2963b 100644 --- a/kernel/src/smp/smp.c +++ b/kernel/src/smp/smp.c @@ -10,8 +10,15 @@ #include #include #include +#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(); diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 6011fb74..d2418d41 100644 --- a/kernel/src/syscall/mod.rs +++ b/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; diff --git a/tools/run-qemu.sh b/tools/run-qemu.sh index 8536b735..3956799e 100644 --- a/tools/run-qemu.sh +++ b/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}"