Hi
Has anyone successfully implemented SYSCALL/SYSRET fastcall as the syscall mechinism in their OS?
I'm struggling to find a sensible way to use them. The obvious problem of not switching to the kernel stack is a pain. In an SMP system it isn't fun to find the kernel stack... without a stack... and would lead to a lot of uglyness in the syscall entry point. I can't just map the per thread kernel stack in a predefined location as all my threads in the same process to share the same PML4.
I read an old posting on a linux kernel development list where two developers were discussing SYSCALL/SYSRET. They mentioned changing the CS after a SYSCALL and before the SYSRET (ie. the thread being preempted while in the kernel) caused the processor to set some internal flag and raise a GP fault. You couldn't then iret to a different thread. Surely this can't be true?
With more googling I found a presentation that mentions a hidden part of the GS register available to use as a pointer to the kernel stack when using SYSCALL. Anyone know anything about this?
A software interrupt is looking better by the minute...
SYSCALL/SYSRET Questions
SYSCALL/SYSRET Questions
All your base are belong to us.
Re: SYSCALL/SYSRET Questions
Basically your create a segment that points to the base of some kind of kernel processor specific information structure, then access the fields using the gs register prefix and manual offsets. So you could essentially store a processor specific SYSCALL stack in this structure then access it in your syscall handler and likewise storing the user RSP. Certain threading systems do the same thing with the FS register iirc. GS should have 2 MSRs to set it's base address in long mode, as well as the "swapgs" instruction which can switch to a kernel specific base address.
Reserved for OEM use.
Re: SYSCALL/SYSRET Questions
Ok, that makes sense.
If I am understanding correctly, you would set the GS Base MSR at each context switch and use SWAPGS to load the Kernel GS base during a SYSCALL?
If I am understanding correctly, you would set the GS Base MSR at each context switch and use SWAPGS to load the Kernel GS base during a SYSCALL?
All your base are belong to us.
Re: SYSCALL/SYSRET Questions
Pretty much, be careful about actually loading the GS register with a selector value though. Doing so will automatically zero the GS base register regardless of the MSR values due to how long mode segmentation functions. If you swapgs afterwards it'll also store that value in the Kernel GS base and possibly a myriad of problems down the line. It's easy enough to work around though.
Reserved for OEM use.
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: SYSCALL/SYSRET Questions
Loading the GS or FS segment register will load them from the GDT (At least IIRC) - but it will, of course, only load the lower 32 bits of the base.
Re: SYSCALL/SYSRET Questions
Thanks for the all the advice. Now working. Much simpler than I first imagined. (I really should have turned the page on the AMD manual).
...And remember boys and girls, use SYSRETQ not SYSRET or you'll end back up in compatibility mode.
Arrrrrghh!
...And remember boys and girls, use SYSRETQ not SYSRET or you'll end back up in compatibility mode.
Arrrrrghh!
All your base are belong to us.