Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
GnoCiYeH committed Nov 3, 2023
1 parent 3012789 commit 9d7f931
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 46 deletions.
4 changes: 2 additions & 2 deletions kernel/src/arch/x86_64/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ impl ArchPCBInfo {
);
}

pub fn init_syscall_stack(&mut self, stack: VirtAddr) {
self.gsdata.set_kstack(stack);
pub fn init_syscall_stack(&mut self, stack: &KernelStack) {
self.gsdata.set_kstack(stack.stack_max_address() - 8);
}

pub fn fsbase(&self) -> usize {
Expand Down
4 changes: 2 additions & 2 deletions kernel/src/arch/x86_64/process/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +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 data segment selector
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);
/// user data segment selector
pub const USER_DS: SegmentSelector = SegmentSelector::new(5, Ring::Ring3);

static mut TSS_MANAGER: TSSManager = TSSManager::new();

Expand Down
19 changes: 19 additions & 0 deletions kernel/src/arch/x86_64/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ unsafe impl SafeForZero for X86_64GSData {}

extern "C" {
fn syscall_int();
fn syscall_64();
}

macro_rules! syscall_return {
Expand Down Expand Up @@ -80,6 +81,24 @@ pub fn arch_syscall_init() -> Result<(), SystemError> {
return Ok(());
}

/// syscall指令初始化
#[no_mangle]
pub unsafe extern "C" fn rs_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);
}

/// 执行第一个用户进程的函数(只应该被调用一次)
///
/// 当进程管理重构完成后,这个函数应该被删除。调整为别的函数。
Expand Down
37 changes: 16 additions & 21 deletions kernel/src/exception/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -330,24 +330,24 @@ ENTRY(syscall_64)
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 $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
leaq syscall_handler(%rip), %rax // FUNC
xchgq %rax, (%rsp)

pushq %rax //rax
pushq %rax // rax

movq %es, %rax
pushq %rax //es
pushq %rax // es
movq %ds, %rax
pushq %rax //ds
xorq %rax, %rax
pushq %rax // ds
xorq %rax, %rax

pushq %rbp
pushq %rdi
Expand All @@ -373,12 +373,7 @@ ENTRY(syscall_64)

callq *%rdx //调用服务程序

// 进入信号处理流程
cli
// 将原本要返回的栈帧的栈指针传入do_signal的第一个参数
// movq %rsp, %rdi
// callq do_signal


// === 恢复调用现场 ===
popq %r15
Expand All @@ -396,7 +391,7 @@ ENTRY(syscall_64)
popq %rdi
popq %rbp

popq %rax // 不允许直接pop到ds
popq %rax // 不允许直接pop到ds
movq %rax, %ds

popq %rax
Expand All @@ -405,11 +400,11 @@ ENTRY(syscall_64)
popq %rax
addq $0x10, %rsp // 弹出变量FUNC和errcode

popq %rcx //pop rip到rcx
popq %rcx // pop rip到rcx

addq $0x8, %rsp //弹出cs
popq %r11 //pop rflags到r11
popq %rsp //Restore rsp
addq $0x8, %rsp // 弹出cs
popq %r11 // pop rflags到r11
popq %rsp // Restore rsp

swapgs
sysretq
3 changes: 1 addition & 2 deletions kernel/src/exception/trap.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,4 @@ void SIMD_exception();
void virtualization_exception();

void syscall_int(); // 系统调用门
void sys_vector_init();
void syscall_64(); // syscall指令入口
void sys_vector_init();
2 changes: 1 addition & 1 deletion kernel/src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ impl ProcessControlBlock {

pcb.arch_info
.lock()
.init_syscall_stack(pcb.syscall_stack.read().stack_max_address() - 8);
.init_syscall_stack(&pcb.syscall_stack.read());

let pcb = Arc::new(pcb);

Expand Down
20 changes: 2 additions & 18 deletions kernel/src/smp/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,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
Expand Down Expand Up @@ -155,7 +156,7 @@ void smp_ap_start_stage2()

apic_timer_ap_core_init();

smp_syscall_init();
rs_init_syscall_64();

sti();
sched();
Expand Down Expand Up @@ -195,23 +196,6 @@ static void __smp__flush_tlb_ipi_handler(uint64_t irq_num, uint64_t param, struc
flush_tlb();
}

void smp_syscall_init()
{
uint64_t efer = rdmsr(MSR_EFER);
efer |= 0x1;
wrmsr(MSR_EFER, efer);

uint16_t syscall_base = 1 << 3;
uint16_t sysret_base = (4 << 3) | 3;
uint32_t high = ((uint32_t)sysret_base << 16) | (uint32_t)syscall_base;
// 初始化STAR寄存器
wrmsr(MSR_STAR, ((uint64_t)high) << 32);

// 初始化LSTAR,该寄存器存储syscall指令入口rip
wrmsr(MSR_LSTAR, (uint64_t)syscall_64);
wrmsr(MSR_SYSCALL_MASK, 0xfffffffe);
}

/**
* @brief 获取当前全部的cpu数目
*
Expand Down

0 comments on commit 9d7f931

Please sign in to comment.