Re: [RFC] TIF_NOTIFY_RESUME, arch/*/*/*signal*.c and all such

From: Martin Schwidefsky
Date: Mon Apr 30 2012 - 04:07:07 EST


On Sun, 29 Apr 2012 05:12:05 +0100
Al Viro <viro@xxxxxxxxxxxxxxxxxx> wrote:

> On Sat, Apr 28, 2012 at 12:32:35AM +0100, Al Viro wrote:
> > On Sat, Apr 28, 2012 at 12:15:26AM +0100, Al Viro wrote:
> >
> > > I think all such architectures need that check lifted to do_notify_resume()
> > > (and the rest needs it killed, of course). Including x86, by the look
> > > of it - we _probably_ can't get there with TIF_NOTIFY_RESUME and
> > > !user_mode(regs), but I'm not entirely sure of that. arm is in about the
> > > same situation; alpha, ppc{32,64}, sparc{32,64} and m68k really can't get
> > > there like that (they all check it in the asm glue). mips probably might,
> > > unless I'm misreading their ret_from_fork()... Fun.
> >
> > Speaking of user_mode() oddities - may I politely inquire what had
> > been smoked to inspire this (in arch/s390/kernel/signal.c):
> > /* This is the legacy signal stack switching. */
> > else if (!user_mode(regs) &&
> > !(ka->sa.sa_flags & SA_RESTORER) &&
> > ka->sa.sa_restorer) {
> > sp = (unsigned long) ka->sa.sa_restorer;
> > }
> > especially when all paths leading to that come through do_signal() that does
> > if (!user_mode(regs))
> > return;
> > on the same regs. It had been like that since 2.3.99pre8 when s390 went
> > into the tree... It looks vaguely similar to i386
> > /* This is the legacy signal stack switching. */
> > if ((regs->ss & 0xffff) != __USER_DS &&
> > !(ka->sa.sa_flags & SA_RESTORER) &&
> > ka->sa.sa_restorer)
> > sp = (unsigned long) ka->sa.sa_restorer;
> > but there the code is at least not unreachable...
>
> While we are at it, can we *ever* reach do_signal() (nevermind deep in its
> guts) with !user_mode(regs)?
> AFAICS, for 31bit possible paths are:
> do_signal()
> <- sysc_sigpending
> <- sysc_work
> <- sysc_tif, having checked for user_mode(%r11)
> <- io_sigpending
> <- io_work_tif
> <- io_work_user
> <- io_work, having checked for user_mode(%r11)
>
> and identical for 64bit. *All* paths into do_signal() go through
> tm __PT_PSW+1(%r11),0x01 # returning to user ?
> and proceed towards do_signal() only if the bit is set. Which is precisely
> what user_mode(%r11) is...
>
> What the hell is going on in that code?

Cut-copy-paste from x86. You are correct that do_signal is only ever called
with user_mode(regs) == 1. This allows us to remove the !user_mode() check
in do_signal and the SA_RESTORER thingy in get_sigframe. I once contemplated
to remove the SA_RESTORER option altogether, because a user space restorer
does not make much sense for s390. The user space restorer needs to
1) restore all registers, and 2) branch back to the interrupted code.
For 2) we need a register which makes 1) impossible to do.
I still have that patch lying around on my hard drive.

--
blue skies,
Martin.

"Reality continues to ruin my life." - Calvin.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/