From 72efa797e58d14095635d1642063fb0cabd6905c Mon Sep 17 00:00:00 2001 From: WangRunji Date: Mon, 29 Apr 2019 02:33:44 +0800 Subject: [PATCH] x86_64: enable interrupt during syscall. set TSS.sp0 through gs. --- kernel/src/arch/x86_64/gdt.rs | 19 +++---------------- kernel/src/arch/x86_64/interrupt/handler.rs | 6 ------ kernel/src/arch/x86_64/interrupt/trap.asm | 15 +++++++-------- kernel/src/arch/x86_64/mod.rs | 2 +- 4 files changed, 11 insertions(+), 31 deletions(-) diff --git a/kernel/src/arch/x86_64/gdt.rs b/kernel/src/arch/x86_64/gdt.rs index ed648e3..42c125c 100644 --- a/kernel/src/arch/x86_64/gdt.rs +++ b/kernel/src/arch/x86_64/gdt.rs @@ -39,10 +39,6 @@ pub struct Cpu { } impl Cpu { - pub fn current() -> &'static mut Self { - unsafe { CPUS[super::cpu::id()].as_mut().unwrap() } - } - fn new() -> Self { Cpu { gdt: GlobalDescriptorTable::new(), @@ -72,18 +68,9 @@ impl Cpu { set_cs(KCODE_SELECTOR); // load TSS load_tss(TSS_SELECTOR); - // for fast syscall: - // store address of TSS to kernel_gsbase - let mut kernel_gsbase = Msr::new(0xC0000102); - kernel_gsbase.write(&self.tss as *const _ as u64); - } - - /// 设置从Ring3跳到Ring0时,自动切换栈的地址 - /// - /// 每次进入用户态前,都要调用此函数,才能保证正确返回内核态 - pub fn set_ring0_rsp(&mut self, rsp: usize) { - trace!("gdt.set_ring0_rsp: {:#x}", rsp); - self.tss.privilege_stack_table[0] = VirtAddr::new(rsp as u64); + // store address of TSS to GSBase + let mut gsbase = Msr::new(0xC0000101); + gsbase.write(&self.tss as *const _ as u64); } } diff --git a/kernel/src/arch/x86_64/interrupt/handler.rs b/kernel/src/arch/x86_64/interrupt/handler.rs index 230ee18..de70864 100644 --- a/kernel/src/arch/x86_64/interrupt/handler.rs +++ b/kernel/src/arch/x86_64/interrupt/handler.rs @@ -213,9 +213,3 @@ fn invalid_opcode(tf: &mut TrapFrame) { fn error(tf: &TrapFrame) { crate::trap::error(tf); } - -#[no_mangle] -pub unsafe extern "C" fn set_return_rsp(tf: *const TrapFrame) { - use crate::arch::gdt::Cpu; - Cpu::current().set_ring0_rsp(tf.add(1) as usize); -} diff --git a/kernel/src/arch/x86_64/interrupt/trap.asm b/kernel/src/arch/x86_64/interrupt/trap.asm index d20528d..2f0424b 100644 --- a/kernel/src/arch/x86_64/interrupt/trap.asm +++ b/kernel/src/arch/x86_64/interrupt/trap.asm @@ -49,8 +49,10 @@ __alltraps: .global trap_ret trap_ret: + # store kernel rsp -> TSS.sp0 mov rdi, rsp - call set_return_rsp + add rdi, 720 + mov gs:[4], rdi # pop fp state offset pop rcx @@ -104,8 +106,6 @@ syscall_entry: # - store rip -> rcx # - load rip - # swap in kernel gs - swapgs # store user rsp -> scratch at TSS.sp1 mov gs:[12], rsp # load kernel rsp <- TSS.sp0 @@ -119,11 +119,8 @@ syscall_entry: push 0 # error_code (dummy) push 0 # trap_num (dummy) - # swap out kernel gs - swapgs - # enable interrupt - # sti + sti push rax push rcx @@ -173,8 +170,10 @@ syscall_return: # disable interrupt cli + # store kernel rsp -> TSS.sp0 mov rdi, rsp - call set_return_rsp + add rdi, 720 + mov gs:[4], rdi # pop fp state offset pop rcx diff --git a/kernel/src/arch/x86_64/mod.rs b/kernel/src/arch/x86_64/mod.rs index bec0e26..f02dd60 100644 --- a/kernel/src/arch/x86_64/mod.rs +++ b/kernel/src/arch/x86_64/mod.rs @@ -15,7 +15,7 @@ pub mod rand; pub mod syscall; pub mod timer; -static AP_CAN_INIT: AtomicBool = ATOMIC_BOOL_INIT; +static AP_CAN_INIT: AtomicBool = AtomicBool::new(false); /// The entry point of kernel #[no_mangle] // don't mangle the name of this function