PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
syscall.h
Go to the documentation of this file.
1#pragma once
2
3#ifndef __ASSEMBLER__
6#endif
7
8/**
9 * @brief System Call Interface.
10 * @defgroup kernel_cpu_syscall Syscall
11 * @ingroup kernel_cpu
12 *
13 * System calls provide a controlled interface for user-space applications to request services from the kernel, such as
14 * file operations, process management, and inter-process communication.
15 *
16 * ## SYSCALL Instruction
17 *
18 * Historically, system calls were invoked using software interrupts (usually `int 0x80`), which are relatively slow due
19 * to overhead from interrupt handling.
20 *
21 * Instead, we use the modern `SYSCALL` instruction, which allows for a faster transition from user mode to kernel mode,
22 * but it is a little more complex to set up.
23 *
24 * ## Calling Convention
25 *
26 * The syscall calling convention mostly follows the standard System V ABI for x86_64 architecture, with the exception
27 * of the argument registers, and the use of the `RAX` register for the syscall number.
28 *
29 * Arguments are passed to syscalls using the `RDI`, `RSI`, `RDX`, `R10`, `R8`, and `R9` registers, in that order. The
30 * syscall number is passed in the `RAX` register.
31 *
32 * After the registers are setup the `syscall` instruction should be called, with the return value is being placed in
33 * the `RAX` register.
34 *
35 * If the return value is `ERR` for a system call that returns an integer or `NULL` for a system call that returns a
36 * pointer. Then the `SYS_ERRNO` syscall can be used to retrieve the associated error code.
37 *
38 * @see [SYSCALL instruction](https://www.felixcloutier.com/x86/syscall)
39 * @see [SYSRET instruction](https://www.felixcloutier.com/x86/sysret)
40 *
41 * @{
42 */
43
44/**
45 * @brief The offset of the `syscallRsp` member in the `syscall_ctx_t` structure.
46 *
47 * Needed to access the syscall context from assembly code.
48 */
49#define SYSCALL_CTX_SYSCALL_RSP_OFFSET 0x0
50
51/**
52 * @brief The offset of the `userRsp` member in the `syscall_ctx_t` structure.
53 *
54 * Needed to access the syscall context from assembly code.
55 */
56#define SYSCALL_CTX_USER_RSP_OFFSET 0x8
57
58#ifndef __ASSEMBLER__
59/**
60 * @brief System Call Numbers.
61 * @enum syscall_number_t
62 */
110
111/**
112 * @brief Syscall flags.
113 * @enum syscall_flags_t
114 */
115typedef enum
116{
118 /**
119 * Forces a fake interrupt to be generated after the syscall completes. This is useful if a syscall does not wish to
120 * return to where it was called from.
121 *
122 * Intended to be used by modifying the interrupt frame stored in the syscall context and setting this flag. As an
123 * example, consider the `SYS_NOTED` syscall.
124 */
127
128/**
129 * @brief Per thread syscall context.
130 * @struct syscall_ctx_t
131 */
132typedef struct
133{
134 uintptr_t syscallRsp; ///< The stack pointer to use when handling syscalls.
135 uintptr_t userRsp; ///< Used to avoid clobbering registers when switching stacks.
136 interrupt_frame_t* frame; ///< If a fake interrupt is generated, this is the interrupt frame to return to.
137 syscall_flags_t flags; ///< Flags for the current syscall.
139
140/**
141 * @brief A syscall descriptor.
142 * @struct syscall_descriptor_t
143 *
144 * Describes a single syscall, its number and the function pointer to the handler.
145 */
151
152/**
153 * @brief Linker defined start of the syscall table.
154 */
156
157/**
158 * @brief Linker defined end of the syscall table.
159 */
161
162/**
163 * @brief Macro to define a syscall.
164 *
165 * Uses the `._syscall_table` linker section to store the syscall descriptor.
166 *
167 * @param num The syscall number, must be unique, check `syscall_number_t`.
168 * @param returnType The return type of the syscall handler, must be `uint64_t` compatible.
169 * @param ... The arguments of the syscall handler, can be no more than 6 arguments (Such that we only use registers to
170 * pass them).
171 */
172#define SYSCALL_DEFINE(num, returnType, ...) \
173 returnType syscall_handler_##num(__VA_ARGS__); \
174 const syscall_descriptor_t __syscall_##num __attribute__((used, section("._syscall_table"))) = { \
175 .number = (num), \
176 .handler = (void*)syscall_handler_##num, \
177 }; \
178 returnType syscall_handler_##num(__VA_ARGS__)
179
180/**
181 * @brief Initialize a syscall context.
182 *
183 * @param ctx The syscall context to initialize.
184 * @param syscallStack The syscall stack of the thread.
185 */
186void syscall_ctx_init(syscall_ctx_t* ctx, const stack_pointer_t* syscallStack);
187
188/**
189 * @brief Load the syscall context into the `MSR_KERNEL_GS_BASE` MSR.
190 *
191 * @param ctx The syscall context to load.
192 */
194
195/**
196 * @brief Sort the syscall table and verify that all syscalls are present.
197 */
198void syscall_table_init(void);
199
200/**
201 * @brief Main C syscall handler.
202 *
203 * This is called from the assembly `syscall_entry()` function.
204 *
205 * Since notes can only be handled when in user space, this function will, if there are notes pending, provide a fake
206 * interrupt context to handle the note as if a interrupt had occurred at the exact same time as the system call began.
207 *
208 * @param frame The interrupt frame containing the CPU state at the time of the syscall.
209 */
211
212/**
213 * @brief Assembly entry point for syscalls.
214 *
215 * The logic for saving/restoring registers and switching stacks is done here before calling `syscall_handler()`.
216 */
217extern void syscall_entry(void);
218
219#endif
220
221/** @} */
void syscall_ctx_init(syscall_ctx_t *ctx, const stack_pointer_t *syscallStack)
Initialize a syscall context.
Definition syscall.c:28
void syscall_table_init(void)
Sort the syscall table and verify that all syscalls are present.
Definition syscall.c:49
syscall_number_t
System Call Numbers.
Definition syscall.h:64
syscall_descriptor_t _syscall_table_start[]
Linker defined start of the syscall table.
syscall_descriptor_t _syscall_table_end[]
Linker defined end of the syscall table.
syscall_flags_t
Syscall flags.
Definition syscall.h:116
void syscall_handler(interrupt_frame_t *frame)
Main C syscall handler.
Definition syscall.c:75
void syscall_ctx_load(syscall_ctx_t *ctx)
Load the syscall context into the MSR_KERNEL_GS_BASE MSR.
Definition syscall.c:36
void syscall_entry(void)
Assembly entry point for syscalls.
@ SYS_SHARE
Definition syscall.h:94
@ SYS_TOTAL_AMOUNT
Definition syscall.h:108
@ SYS_MMAP
Definition syscall.h:83
@ SYS_MOUNT
Definition syscall.h:102
@ SYS_STAT
Definition syscall.h:82
@ SYS_WRITE
Definition syscall.h:78
@ SYS_SYMLINK
Definition syscall.h:101
@ SYS_LINK
Definition syscall.h:93
@ SYS_NANOSLEEP
Definition syscall.h:68
@ SYS_SETUP
Definition syscall.h:105
@ SYS_YIELD
Definition syscall.h:88
@ SYS_GETTID
Definition syscall.h:71
@ SYS_THREAD_EXIT
Definition syscall.h:66
@ SYS_READ
Definition syscall.h:77
@ SYS_OPEN2
Definition syscall.h:75
@ SYS_CLOSE
Definition syscall.h:76
@ SYS_POLL
Definition syscall.h:81
@ SYS_UNMOUNT
Definition syscall.h:103
@ SYS_ERRNO
Definition syscall.h:69
@ SYS_EPOCH
Definition syscall.h:73
@ SYS_MUNMAP
Definition syscall.h:84
@ SYS_OPEN
Definition syscall.h:74
@ SYS_IOCTL
Definition syscall.h:80
@ SYS_TEARDOWN
Definition syscall.h:106
@ SYS_ARCH_PRCTL
Definition syscall.h:104
@ SYS_ENTER
Definition syscall.h:107
@ SYS_OPENAT
Definition syscall.h:97
@ SYS_GETPID
Definition syscall.h:70
@ SYS_NOTIFY
Definition syscall.h:98
@ SYS_GETDENTS
Definition syscall.h:86
@ SYS_BIND
Definition syscall.h:96
@ SYS_THREAD_CREATE
Definition syscall.h:87
@ SYS_DUP
Definition syscall.h:89
@ SYS_EXITS
Definition syscall.h:65
@ SYS_READLINK
Definition syscall.h:100
@ SYS_CLAIM
Definition syscall.h:95
@ SYS_FUTEX
Definition syscall.h:91
@ SYS_DUP2
Definition syscall.h:90
@ SYS_SPAWN
Definition syscall.h:67
@ SYS_MPROTECT
Definition syscall.h:85
@ SYS_NOTED
Definition syscall.h:99
@ SYS_REMOVE
Definition syscall.h:92
@ SYS_UPTIME
Definition syscall.h:72
@ SYS_SEEK
Definition syscall.h:79
@ SYSCALL_FORCE_FAKE_INTERRUPT
Definition syscall.h:125
@ SYSCALL_NORMAL
Definition syscall.h:117
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:43
Trap Frame Structure.
Definition interrupt.h:195
Structure to define a stack in memory.
Per thread syscall context.
Definition syscall.h:133
uintptr_t userRsp
Used to avoid clobbering registers when switching stacks.
Definition syscall.h:135
interrupt_frame_t * frame
If a fake interrupt is generated, this is the interrupt frame to return to.
Definition syscall.h:136
uintptr_t syscallRsp
The stack pointer to use when handling syscalls.
Definition syscall.h:134
syscall_flags_t flags
Flags for the current syscall.
Definition syscall.h:137
A syscall descriptor.
Definition syscall.h:147