Add sysenter fast system call support to DragonWare's kernel#2
Draft
tseli0s wants to merge 15 commits into
Draft
Add sysenter fast system call support to DragonWare's kernel#2tseli0s wants to merge 15 commits into
sysenter fast system call support to DragonWare's kernel#2tseli0s wants to merge 15 commits into
Conversation
Preparation to introduce proper sysenter/sysexit support in DragonWare and reduce the system call overhead significantly by only pushing what's necessary and not loading a full InterruptStackFrame. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
From v0.0.2 forwards, the kernel is going to use registers ebx, esi, edi and ebp for arguments in the exposed system calls, with eax used as the system call number. This is in preparation to move into sysenter/sysexit, which need to have ecx/edx preserved but the kernel uses them for the second and third arguments of system calls. Obviously this is a breaking change, so libc's shim handlers to trigger a system call are also updated to use the appropriate registers. Five-parameter system call support has been temporarily removed. Note that temporarily the SYSCALL_TICKS_SINCE_BOOT system call is broken, and as such, cannot be used. This will be addressed in another commit. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
No longer defined (The kernel supports up to four parameters per system call for now). Additionally drop __make_syscall_ia32_5param_reti32() which is a jump to that function. Both definitions of these two stubs were removed in 65091ae. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
See commit a886e1d of which this one is a supplement of. System calls do not need a complete InterruptStackFrame - More than half the state saved in every interrupt is completely unused. Additionally, neither DragonWareSyscall nor POSIXSyscall should return any values - They are ignored entirely, so no point in even returning anything. That was a remnant from when interrupts were the only way to switch tasks around. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
Update the interrupt handling code to copy the system call registers returned by DragonWareSyscall to the InterruptStackFrame of the function. Otherwise no matter what DragonWareSyscall returns in the registers, it will be completely ignored, like the system call was never performed. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
…ailable Check if the sysenter/sysexit instruction pair is supported on the machine. If so, the kernel has enabled support for it and it can be used for faster system calls. If not, then the old, software interrupt path will be used instead. libc will install the correct gate during early initialization by detecting the feature support using CPUID. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
Update the sysenter code to create a SystemCallFrame by pushing all the registers expected inside SystemCallFrame on the stack and then passing the stack pointer as the argument of DragonWareSyscall. This effectively means that now DragonWare supports sysenter to some extent, although support is buggy and incomplete. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
It was only used for supporting _DWRaiseIOPL in both software interrupts and the WIP sysenter support, but due to incompatibilities between the two, the register will no longer be saved and the system call will be replaced with a proper TSS I/O bitmap instead. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
Arithmetic on a NULL pointer (Address 0) is undefined behaviour and we cannot rely on it. Using __builtin_offsetof() is a better approach that also allows for some compiler optimizations. Additionally, clean up some code like the unused foreach() macro and use parentheses in places where precedence matters. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
They were a remnant from before the kernel used ports for all IPC communication. They only waste memory and lines of code, so they can be dropped safely. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
It is no longer used and the functionality is replaced by another system call that's in the works. See also a2a28d0 for the relevant previous part. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
This system call replaces _DWRaiseIOPL (From v0.0.1 relying on EFLAGS state) with a more secure function, that is also fine grained and technically a little faster. The relevant userland will be updated in another commit. Replacing _DWRaiseIOPL was a necessity due to the limitations of sysenter and its very minimal context saving. Making the kernel work well with both mechanisms (software interrupts and sysenter) to preserve hardware compatibility requires some refactoring in this system call. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
…ocess` It has to be implemented otherwise context switching will break any process that previously had the right to access a port. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
See commit d0f2f10 for more details. The _DWRaiseIOPL system call has been dropped and has no effect anymore, and the system call number now corresponds to _DWRequestPorts. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
Per the Intel Developer Manuals: "RFLAGS.IF := 0;" Meaning they are automatically cleared when `sysenter` is executed, and there's no reason to execute cli manually. Interrupts still have to be manually reenabled before returning from a system call made using sysenter. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
sysenter/sysexitare a pair of instructions introducing low overhead ring 0 entries. From https://wiki.osdev.org/SYSENTER:"Executes a fast call to a level 0 system procedure or routine. SYSENTER is a companion instruction to SYSEXIT.
The instruction is optimized to provide the maximum performance for system calls from user code running at privilege level 3 to
operating system or executive procedures running at privilege level 0." -- Intel IA-32 (64) programming manual, volume 2B.
For a microkernel like DragonWare, where system calls are done for almost every task (Because message passing is done using system calls), using this instruction can be very beneficial to performance, reducing the cycles needed to enter the kernel to about half or even more.