#include #include #include #include #include #include // TODO: Refactor to only push callee-saved registers. [[__naked]] void arch_syscall_stub() { asm volatile( " swapgs\n" " mov gs:%c0, rsp\n" // user_stack " mov rsp, gs:%c1\n" // kernel_stack " cld\n" "1:\n" " push %c3\n" // ss " push gs:%c0\n" " push r11\n" // rflags " push %c2\n" // cs " push rcx\n" // rip " push 0x00\n" // arch_context::error " push 0x00\n" // arch_context::isr " push rax\n" " push rbx\n" " push rcx\n" " push rdx\n" " push rbp\n" " push rdi\n" " push rsi\n" " push r8\n" " push r9\n" " push r10\n" " push r11\n" " push r12\n" " push r13\n" " push r14\n" " push r15\n" " xor rbp, rbp\n" " mov rdi, rsp\n" // SysV ABI first argument. " call %4\n" // Call syscall handler. " cli\n" " pop r15\n" " pop r14\n" " pop r13\n" " pop r12\n" " pop r11\n" " pop r10\n" " pop r9\n" " pop r8\n" " pop rsi\n" " pop rdi\n" " pop rbp\n" " pop rdx\n" " pop rcx\n" " pop rbx\n" " pop rax\n" " add rsp, 0x10\n" // Skip .error and .isr fields "2:\n" " mov rsp, gs:%c0\n" // user_stack " swapgs\n" " sysretq\n" : : "i"(offsetof(struct percpu, user_stack)), // 0 "i"(offsetof(struct percpu, kernel_stack)), // 1 "i"(offsetof(struct gdt, user_code64) | CPL_USER), // 2 "i"(offsetof(struct gdt, user_data) | CPL_USER), // 3 "r"(syscall_dispatch) // 4 ); }