glibc binaries w/ sysenter support
After quite some fiddling we finally have some glibc binaries with sysenter support. The problems were not in the sysenter code but in coordinating everything in ld.so so that it works on old kernels (without TLS support).
Anyway, the result can be downloaded from
ftp://people.redhat.com/drepper/glibc/2.3.1-25/
These RPMs are drop-in replacements for the ones in the last Red Hat beta, released about a week ago. They haven't been tested in any other environment. They also use NPTL as the default libpthread. As is the case with every beta release code, do *not* install them on production machines. We see no problems with the new code but your mileage may vary. If you see problems ideally file them in Red Hat's bugzilla (remember these are RH-specific binaries). Alternatively send reports to [email protected]. If you suspect the problem is related to the kernel side you know where to post.
Signature · 3 lines
--------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `---------------------------
Quoted 9 lines · Ulrich Drepper
After quite some fiddling we finally have some glibc binaries with sysenter support. The problems were not in the sysenter code but in coordinating everything in ld.so so that it works on old kernels (without TLS support).
Anyway, the result can be downloaded from
ftp://people.redhat.com/drepper/glibc/2.3.1-25/
Thanks.
Having a full system like this showed a few special cases in sysenter handling, where some system calls really depend on the old "iret" return path.
Notably, "sys_iopl()" requires the iret path because that's the only way to restore the full eflags, and "execve()" requires the iret return path because it needs to start up the new process with fixed values in %edx/%ebx, and the stack has a new layout and no longer contains the required sysexit fixup code.
I've pushed the fix for both of these issues to the kernel -bk trees.
Without the fix, a system with sysenter support would not boot up cleanly with these libraries due to the execve() issues, and X wouldn't start because of the iopl() problem.
With this in place, I've not seen any strange behaviour, and "lmbench" reports
Processor, Processes - times in microseconds - smaller is better ---------------------------------------------------------------- Host OS Mhz null null open selct sig sig fork exec sh call I/O stat clos inst hndl proc proc proc --------- ------------- ---- ---- ---- ---- ---- ----- ---- ---- ---- ---- ---- i686-linu Linux 2.5.53 2380 0.7 1.1 5 7 0.04K 1.2 3 0.2K 1K 3K i686-linu Linux 2.5.53 2380 0.7 1.1 5 7 0.04K 1.2 3 0.2K 1K 3K i686-linu Linux 2.5.53 2380 0.7 1.1 5 7 0.04K 1.2 3 0.2K 1K 3K i686-linu Linux 2.5.53 2380 0.2 0.6 5 6 0.04K 0.7 3 0.2K 1K 3K i686-linu Linux 2.5.53 2380 0.2 0.6 5 6 0.04K 0.7 3 0.2K 1K 3K i686-linu Linux 2.5.53 2380 0.2 0.6 5 6 0.04K 0.7 3 0.2K 1K 3K
(the three first entries are with the old glibc, three last entries are with the new one - note the null call/io and signal install improvements).
Linus
Uli,
can you tell me what the new glibc does for different "clone()" system
calls? It turns out that some of the different process creation calls are rather nasty to handle with the "call *syscallptr" approach. We have a few differenct cases:
- vfork() is nasty, because it must not have a stack frame that the parent needs and that might get destroyed by the child.
- clone(.. newesp != 0 ..) is nasty, because the esp correction depends on just what kind of system call it was, and the current kernel doesn't know and really doesn't even _want_ to know.
I know glibc does the inlined "int 0x80" for the vfork() case, but I wonder if you saw the problem for thread creation? I think that one has to use the old-style inlined "int 0x80" too in order to avoid stack confusion.. And since the glibc "clone()" wrapper call gives the user the option to set a non-zero ESP, that one has to do it too.
(Both of these are really independent of "sysenter" itself, and will be visible even on machines without any sysenter support, since they are both stack offset issues caused simply by the fact that we use a trampoline to jump to the system call).
Comments? Can anybody find any other nasty cases where the stack pointer matters for the system call (or an argument is used for a start ptr return value)?
Linus
Quoted 2 lines · Linus Torvalds
can you tell me what the new glibc does for different "
clone()" system
calls?
clone() and vfork() both use int $0x80. The vfork() problem is obvious. And the way we use clone() with a separate stack for the child it is easy to see that we cannot prepare the stack appropriately for both situations. When the child is started it returns with a carefully crafted stack which among other values find the start functions address on the stack.
There might be a way to make this use int and vsyscall at the same time but I don't think it is worth it.
Signature · 3 lines
--------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `---------------------------