Syscalls versus Call Gates
Posted: Wed Jul 16, 2008 3:32 am
Which are pros and cons of syscalls and pros and cons of call gates? Which is the fastest method to handle user to kernel interfacing?
The Place to Start for Operating System Developers
http://f.osdev.org/
Modern X86 operating systems are transitioning away from CALL FAR callgates. With the introduction of SYSENTER/SYSEXIT and SYSCALL/SYSRET, a new faster mechanism was introduced for control transfers for x86 programs. [...]
It should be noted that call gates are more flexible than the SYSENTER/SYSEXIT and SYSCALL/SYSRET instructions since unlike the latter two, call gates allow for changing from an arbitrary privilege level to an arbitrary privilege level. The fast SYS* instruction only allow control transfers from ring 3->0 and vice versa. Upon comparing call gates to interrupts, call gates are significantly faster.
So call gates are faster... But why most operating systems use interrupts?Solar wrote:Wikipedia writes about Call Gates:
Modern X86 operating systems are transitioning away from CALL FAR callgates. With the introduction of SYSENTER/SYSEXIT and SYSCALL/SYSRET, a new faster mechanism was introduced for control transfers for x86 programs. [...]
It should be noted that call gates are more flexible than the SYSENTER/SYSEXIT and SYSCALL/SYSRET instructions since unlike the latter two, call gates allow for changing from an arbitrary privilege level to an arbitrary privilege level. The fast SYS* instruction only allow control transfers from ring 3->0 and vice versa. Upon comparing call gates to interrupts, call gates are significantly faster.
But managed code is slower than machine code. Or not?AJ wrote:3. Managed Code - this has the potential to be a very fast system as you do not need any privilege level / task space switches. It also has the potential to be very unsecure/unstable if you don't implement your base kernel and JIT compiler well. Although the system calls are potentially fast, JIT compilation could slow down your code generally.
Given the choice between software interrupts, call gates, SYSENTER and SYSCALL, why not just implement all of them?Jeko wrote:Which are pros and cons of syscalls and pros and cons of call gates? Which is the fastest method to handle user to kernel interfacing?
So why don't use INT3 instead of INT80?Brendan wrote:Hi,
Given the choice between software interrupts, call gates, SYSENTER and SYSCALL, why not just implement all of them?Jeko wrote:Which are pros and cons of syscalls and pros and cons of call gates? Which is the fastest method to handle user to kernel interfacing?
Note1: if the CPU doesn't support the SYSENTER and/or SYSCALL instructions, you can emulate the instructions inside your invalid opcode exception handler. This would be slower than a software interrupt, but it's more fun than doing "if (CPU_supports_SYSENTER() ) { FOO } else { BAR }" everywhere.
Note2: software interrupts are slower than call gates, but "INT n" only costs 2 bytes while a "CALL FAR" costs 7 bytes, so if you're optimizing for size (e.g. application startup code that's only run once) and don't want to know if SYSENTER/SYSCALL are supported then using a software interrupt is better. The "INT3" instruction is only one byte (which makes it the smallest possible option) but it's probably better to use it for debugging purposes.
Note3: For 64-bit code, just use SYSCALL. The other options are for 16-bit and/or 32-bit code (including 16-bit and/or 32-bit code running under a 64-bit OS).
Cheers,
Brendan
Do you mean int 0x06 which is the Invalid Opcode Exception? If you did it that way, you wouldn't know if it really is an invalid opcode, so you need to do the checks suggested by Brendan.Jeko wrote:So why don't use INT3 instead of INT80?
I mean, why for syscall Linux use int 0x80 and not int 3 if int 3 opcode is smaller?AJ wrote:Do you mean int 0x06 which is the Invalid Opcode Exception? If you did it that way, you wouldn't know if it really is an invalid opcode, so you need to do the checks suggested by Brendan.Jeko wrote:So why don't use INT3 instead of INT80?
Cheers,
Adam
You have the EIP where the exception occurred - simply check the Opcode (which can be found in the Intel Manuals).However when an invalid opcode exception occurs how can I check that it's a SYSCALL/SYSENTER or a SYSRET/SYSEXIT?
I know that INT 3 is the Breakpoint Exception...AJ wrote:You really need to do some background reading and look at the Intel Manuals. Int 0x03 is the Breakpoint Exception - INT 0x00-0x1F should be reserved by your kernel for handling CPU exceptions.
INT 3 is the breakpoint exception, but I can use it how I want.Brendan wrote:The "INT3" instruction is only one byte (which makes it the smallest possible option) but it's probably better to use it for debugging purposes.
JIT compilation is not a requirement for so-called "managed code". The only requirement is the ability to verify the code for type-safety before it runs, and to disallow modifying the code.AJ wrote:3. Managed Code - this has the potential to be a very fast system as you do not need any privilege level / task space switches. It also has the potential to be very unsecure/unstable if you don't implement your base kernel and JIT compiler well. Although the system calls are potentially fast, JIT compilation could slow down your code generally.
Depends how it's implemented. There is a lot of general misunderstanding about how it works. I suggest reading the Singularity research papers if you want to know more.Jeko wrote:But managed code is slower than machine code. Or not?
Whether or not there is a virtual address space for each process becomes optional with software isolation. In Singularity for example, it is a configurable option (maybe a compile-time option for the kernel, I'm not sure).And with managed code there isn't a fully virtual space for each process. Am I right?
You can, however then you become limited with your debugging options. Int 3 (as a single opcode) is useful because a debugger can replace any instruction with it to create a breakpoint. You can replace a two byte instruction with a two byte opcode easily enough and so on, but it becomes more difficult when the instruction you want to break on is only one byte. For example, say you have:Jeko wrote:INT 3 is the breakpoint exception, but I can use it how I want.
Code: Select all
func1:
add eax, 2;
ret;
func2:
mov eax, 5;
call func1;
ret;
I think managed code MUST be slower than machine code. It's normal.Colonel Kernel wrote:Depends how it's implemented. There is a lot of general misunderstanding about how it works. I suggest reading the Singularity research papers if you want to know more.Jeko wrote:But managed code is slower than machine code. Or not?
No, not necessarily. Managed code is checked once, to verify that it doesn't do anything dangerous. After that, it can be run at full speed.Jeko wrote:I think managed code MUST be slower than machine code. It's normal.