On Tue, Sep 11, 2012 at 10:12:56AM +0200, Ralf Baechle wrote: > On Sun, Sep 09, 2012 at 03:30:08PM -0400, Rich Felker wrote: > > > Hi all, > > The kernel syscall entry/exit code seems to always save and restore > > r25. Is this stable/documented behavior I can rely on? If there's a > > reason it _needs_ to be preserved, knowing that would help convince me > > it's safe to assume it will always be done. The intended usage is to > > be able to make syscalls (where the syscall # is not a constant that > > could be loaded with lwi) without a stack frame, as in "move $2,$25 ; > > syscall". > > Since there is no place where the syscall interface is documented other > than in the code itself, I've written a new wiki article > > http://www.linux-mips.org/wiki/Syscall > > as start. It's still lacking on the more obscure points but it at least > should have have answered your question, had it already existed when you > asked. Thanks! Some comments... In the table, $a0 ... $a2/$a7 except $a3 is unclear. Do you mean to say $a0 ... $a2 on o32 and also $a4 ... $a7 on all other ABIs? If so I think it would make sense to put those ranges as separate lines in the table, so it's clear that the second group are not preserved on o32 (if they were, they would also have solved my problem). As for $a3 4th syscall argument $a3 set to 0/1 for success/error Does the kernel guarantee 0/1, or is it 0/nonzero? This could matter to asm programmers using the syscall ABI who want to do bit twiddling. Syscall restarting is a special case where $v0, $v1 and $a3 will stay unmodified. Even the program counter will stay unmodified so the same syscall will be executed again. This is something that does not matter to application programmers but may become visible in debuggers. Syscall restarting is something that is used internally by the kernel, for example when during a large read(2) syscall the kernel receives a signal. The way syscall restarting works does matter to userspace, although only to very low-level code. In musl (http://www.etalabs.net/musl), the syscall routine for cancellation-point syscalls uses labels in the asm before checking the cancellation flag and immediately after the syscall instruction so that the signal handler that processes thread cancellation can examine the saved program counter in the ucontext_t it receives and determine whether the interrupted code is at a cancellable syscall or not, with no race conditions. The glibc/NPTL approach of wrapping a plain syscall with code to change to async cancellation mode and back has extremely dangerous race conditions, and my approach in musl of examining the program counter and comparing it against asm labels is the only solution I've seen that's race-free. Rich