cloudius-systems / osv

OSv, a new operating system for the cloud.
osv.io
Other
4.12k stars 605 forks source link

syscall: use GS register to store syscall stack address #1267

Closed wkozaczuk closed 1 year ago

wkozaczuk commented 1 year ago

The original syscall implementation utilized the TCB (Thread Control Block) to store the syscall stack address. On each context switch, the FS segment register would be reset to point to the thread-specific TCB where syscall handler would fetch its stack address.

In order to support statically linked executables that allocate and use their own TCB, OSv needs to be able to switch the FS register between the user and kernel address when handling syscalls. The syscall handler can no longer fetch its stack address from kernel TCB because the FS register points to the app TCB. In order to break this dependency, this patch changes all relevant code to move the syscall stack address and syscall caller stack pointer to the per-CPU memory area addressed by the GS segment register.

To that end, we define a new structure - syscall_stack_descriptor - that describes a syscall stack: its top and SYSCALL caller stack pointer. Then, we add a new field _syscall_stack_descriptor to the thread_state to store each thread-allocated syscall stack information.

In addition, we add a new field _current_syscall_stack_descriptor to the per-cpu structure arch_cpu and initialize each cpu GS register to point to it. Finally, the thread::switch_to() is changed to update the stack_top and caller_stack_pointer fields of _current_syscall_stack_descriptor on each context switch so that the syscall handler can fetch syscall stack address using GS segment.