Re: [RFC] Attempt to clean up sigsuspend et al
flat view
From: David Woodhouse <dwmw2@infradead.org>
Date: 2005-11-13 11:58:27
On Sun, 2005-11-13 at 21:09 +1100, Paul Mackerras wrote:
quoted
We don't need to do it on entry; we can do it on exit. If do_signal() sees that the nvgprs weren't saved in the pt_regs it's playing with, then it can set a new TIF_SAVENVPGRS_TO_SIG_FRAME bit. I don't think we even need to store a pointer saying where to put them -- the signal frame will always be at the top of the userspace stack.Two problems with that: (1) for *sigsuspend, if do_signal returns 0, then we need to go back and keep waiting, and (2) it doesn't handle the other syscalls that need the full register set, such as fork, clone etc. Also, for the *sigsuspend case, we need to pass the saved signal set to do_signal, not NULL (as the call from the exception exit path does).
It doesn't address fork/vfork/clone; certainly. I haven't really looked at that code path at all yet. It was the *suspend() functions which offended me, mostly because I need similar behaviour for pselect() and ppoll() and I didn't want to add to the mess. But I think other things you mention are OK -- we'd still call do_signal() from *sigsuspend() just as we do at the moment, with the same loop. It's just that do_signal() would notice that the nvgprs aren't saved, and would set the TIF_SAVENVPGRS_TO_SIG_FRAME bit. .. if (!regs->trap & 1) set_thread_flag(TIF_SAVENVGPRS_SIG); We end up returning to userspace via entry.S, and the code there notices the SAVENVGPRS bit and saves _just_ r14-r31 into the signal frame. It doesn't have to call do_signal() again, so doesn't have to get the right saved signal mask when doing so. (Actually in the case of swapcontext() we don't know that the nvgprs should be saved in a signal frame at the top of the userspace stack; the context will be elsewhere. We probably do need to store a pointer in the thread_info, but that's OK too) -- dwmw2