Skip to main content

kernel/arch/x86_64/cpu/
userspace.rs

1// SPDX-License-Identifier: GPL-3.0-only
2//! Userspace transition Code
3//!
4//! Authors: MarioS271
5
6use crate::lib::addr::VirtAddr;
7use crate::state::kstate::KSTATE;
8
9/// First transition into userspace; uses a fake stack frame and `iretq` to jump to userspace
10/// for the first time
11///
12/// # Safety
13/// The caller must guarantee the following:
14/// - The process's address space is fully and correctly mapped
15/// - `entry` needs to point to valid executable code in that address space
16/// - `stack_top` needs to be valid, mapped and user-accessible
17/// - The kernel higher half needs to be mapped in the address space
18pub unsafe fn initial_userspace_jump(root_page_phys: u64, entry: u64, stack_top: VirtAddr) -> ! {
19    let cs = KSTATE.cpu.global_cpu_state().user_code_selector() as u64;
20    let ss = KSTATE.cpu.global_cpu_state().user_data_selector() as u64;
21
22    unsafe {
23        core::arch::asm!(
24            "mov cr3, {pml4}",
25            "push {ss}",
26            "push {rsp}",
27            "push {rflags}",
28            "push {cs}",
29            "push {rip}",
30
31            "xor eax, eax",
32            "xor ebx, ebx",
33            "xor ecx, ecx",
34            "xor edx, edx",
35            "xor esi, esi",
36            "xor edi, edi",
37            "xor ebp, ebp",
38            "xor r8d, r8d",
39            "xor r9d, r9d",
40            "xor r10d, r10d",
41            "xor r11d, r11d",
42            "xor r12d, r12d",
43            "xor r13d, r13d",
44            "xor r14d, r14d",
45            "xor r15d, r15d",
46
47            "iretq",
48
49            pml4 = in(reg) root_page_phys,
50            ss = in(reg) ss,
51            rsp = in(reg) stack_top.as_u64(),
52            rflags = in(reg) 0x202u64,
53            cs = in(reg) cs,
54            rip = in(reg) entry,
55            options(noreturn)
56        )
57    }
58}