axhal/arch/x86_64/
syscall.rs

1use x86_64::addr::VirtAddr;
2use x86_64::registers::model_specific::{Efer, EferFlags, KernelGsBase, LStar, SFMask, Star};
3use x86_64::registers::rflags::RFlags;
4use x86_64::structures::tss::TaskStateSegment;
5
6use super::{GdtStruct, TrapFrame};
7
8#[unsafe(no_mangle)]
9#[percpu::def_percpu]
10static USER_RSP_OFFSET: usize = 0;
11
12core::arch::global_asm!(
13    include_str!("syscall.S"),
14    tss_rsp0_offset = const core::mem::offset_of!(TaskStateSegment, privilege_stack_table),
15    ucode64 = const GdtStruct::UCODE64_SELECTOR.0,
16);
17
18pub(super) fn handle_syscall(tf: &mut TrapFrame) {
19    tf.rax = crate::trap::handle_syscall(tf, tf.rax as usize) as u64;
20}
21
22#[unsafe(no_mangle)]
23fn x86_syscall_handler(tf: &mut TrapFrame) {
24    super::tls::switch_to_kernel_fs_base(tf);
25    #[cfg(target_os = "none")]
26    super::trap::unmask_irqs(tf);
27    handle_syscall(tf);
28    crate::trap::post_trap_callback(tf, true);
29    super::tls::switch_to_user_fs_base(tf);
30    #[cfg(target_os = "none")]
31    super::trap::mask_irqs();
32}
33
34/// Initializes syscall support and setups the syscall handler.
35pub fn init_syscall() {
36    unsafe extern "C" {
37        fn syscall_entry();
38    }
39    unsafe {
40        LStar::write(VirtAddr::new(syscall_entry as usize as _));
41        Star::write(
42            GdtStruct::UCODE64_SELECTOR,
43            GdtStruct::UDATA_SELECTOR,
44            GdtStruct::KCODE64_SELECTOR,
45            GdtStruct::KDATA_SELECTOR,
46        )
47        .unwrap();
48        SFMask::write(
49            RFlags::TRAP_FLAG
50                | RFlags::INTERRUPT_FLAG
51                | RFlags::DIRECTION_FLAG
52                | RFlags::IOPL_LOW
53                | RFlags::IOPL_HIGH
54                | RFlags::NESTED_TASK
55                | RFlags::ALIGNMENT_CHECK,
56        ); // TF | IF | DF | IOPL | AC | NT (0x47700)
57        Efer::update(|efer| *efer |= EferFlags::SYSTEM_CALL_EXTENSIONS);
58        KernelGsBase::write(VirtAddr::new(0));
59    }
60}