Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

支持syscall指令 #417

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
19ab0b0
初步实现clone系统调用
GnoCiYeH Oct 12, 2023
01c5806
futex部分实现
GnoCiYeH Oct 15, 2023
9379b96
thread
GnoCiYeH Oct 17, 2023
b53ac80
Merge branch 'patch-thread' of github.com:GnoCiYeH/DragonOS into patc…
GnoCiYeH Oct 18, 2023
9ad296b
Merge remote-tracking branch 'heyicong/patch-futex' into patch-thread
GnoCiYeH Oct 24, 2023
4e2655f
Merge remote-tracking branch 'origin/master' into patch-thread
GnoCiYeH Oct 26, 2023
b6e9442
实现了线程,初步实现futex机制,添加了几个小的系统调用
GnoCiYeH Oct 26, 2023
1139b44
fmt
GnoCiYeH Oct 26, 2023
f3e9caa
update
GnoCiYeH Oct 26, 2023
3746edd
update
GnoCiYeH Oct 26, 2023
6401b91
update
GnoCiYeH Oct 26, 2023
a7a84b5
删除有问题的汇编
GnoCiYeH Oct 26, 2023
6a18f75
fmt
GnoCiYeH Oct 26, 2023
b835f25
update
GnoCiYeH Oct 27, 2023
45eece6
更改pcb引用计数问题
fslongjin Oct 28, 2023
00c3dd0
解决general_protection问题
GnoCiYeH Oct 29, 2023
d0a4f05
weak
fslongjin Oct 29, 2023
24edab3
能跑
fslongjin Oct 29, 2023
758d54f
修改futex_wait失败的问题
GnoCiYeH Oct 30, 2023
80cb928
fmt
GnoCiYeH Oct 30, 2023
a2e7a43
释放futexkey,消除日志
GnoCiYeH Oct 31, 2023
1b70349
warning
GnoCiYeH Oct 31, 2023
e8db16b
添加rust重构版本的HPET驱动和tsc驱动,并使用HPET校准tsc频率和cpu总线频率 (#412)
fslongjin Oct 26, 2023
9f3a834
完成e1000e驱动 (#393)
Hdksg10 Oct 29, 2023
65f4be9
解决死锁bug
GnoCiYeH Oct 31, 2023
5e5a104
解决warning
GnoCiYeH Oct 31, 2023
16137fa
Merge remote-tracking branch 'origin/master' into patch-thread
GnoCiYeH Oct 31, 2023
14c2478
1
fslongjin Nov 1, 2023
f78f361
支持syscall以及sysret进行系统调用
GnoCiYeH Nov 2, 2023
d99dcc8
Merge branch 'patch-thread' into patch-syscall-instruction
GnoCiYeH Nov 2, 2023
2d40ffa
Merge branch 'master' into patch-syscall-instruction
GnoCiYeH Nov 2, 2023
3012789
fmt
GnoCiYeH Nov 2, 2023
9d7f931
update
GnoCiYeH Nov 3, 2023
465072b
为bsp初始化syscall64指令
fslongjin Nov 3, 2023
4c8a1a2
默认启用virtio
fslongjin Nov 3, 2023
c5b84a7
注释
GnoCiYeH Nov 3, 2023
eb0c96e
修复初始化程序使用syscall指令出错的问题
GnoCiYeH Nov 4, 2023
da7c33f
Merge branch 'master' into heyicong-patch-syscall-instruction
fslongjin Nov 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ cppcheck.xml
/target/
Cargo.lock
.cache
compile_commands.json
compile_commands.json
10 changes: 9 additions & 1 deletion kernel/src/arch/x86_64/c_adapter.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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();
}
12 changes: 6 additions & 6 deletions kernel/src/arch/x86_64/ipc/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
// 若没有正在等待处理的信号,或者将要返回到的是内核态,则启用中断,然后返回
Expand Down
105 changes: 79 additions & 26 deletions kernel/src/arch/x86_64/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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,
Expand All @@ -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>,
}
Expand All @@ -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,
Expand All @@ -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;
}
Expand Down Expand Up @@ -184,34 +183,47 @@ 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;
}
}

pub unsafe fn save_gsbase(&mut self) {
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;
}
}

pub unsafe fn restore_fsbase(&mut self) {
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);
}
}

pub unsafe fn restore_gsbase(&mut self) {
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
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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`钩子函数
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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",
Expand Down
7 changes: 4 additions & 3 deletions kernel/src/arch/x86_64/process/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
55 changes: 51 additions & 4 deletions kernel/src/arch/x86_64/syscall.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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(());
}

Expand All @@ -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 changes: 4 additions & 0 deletions kernel/src/driver/interrupt/apic/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
// ==========外部中断控制器========
Expand Down
Loading