LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Christophe Leroy <christophe.leroy@csgroup.eu>
To: Nicholas Piggin <npiggin@gmail.com>,
	linuxppc-dev@lists.ozlabs.org,
	Michael Ellerman <mpe@ellerman.id.au>
Cc: cmr@codefail.de
Subject: Re: [PATCH] powerpc/signal64: Don't read sigaction arguments back from user memory
Date: Tue, 15 Jun 2021 08:22:13 +0200	[thread overview]
Message-ID: <e01caafd-e96d-b31b-8983-4c0a9d285fc8@csgroup.eu> (raw)
In-Reply-To: <e84f44e5-46a2-4076-b565-038057329be5@csgroup.eu>



Le 14/06/2021 à 13:49, Christophe Leroy a écrit :
> 
> 
> Le 14/06/2021 à 07:49, Nicholas Piggin a écrit :
>> Excerpts from Christophe Leroy's message of June 14, 2021 3:30 pm:
>>>
>>>
>>> Le 14/06/2021 à 03:32, Nicholas Piggin a écrit :
>>>> Excerpts from Michael Ellerman's message of June 10, 2021 5:29 pm:
>>>>> When delivering a signal to a sigaction style handler (SA_SIGINFO), we
>>>>> pass pointers to the siginfo and ucontext via r4 and r5.
>>>>>
>>>>> Currently we populate the values in those registers by reading the
>>>>> pointers out of the sigframe in user memory, even though the values in
>>>>> user memory were written by the kernel just prior:
>>>>>
>>>>>     unsafe_put_user(&frame->info, &frame->pinfo, badframe_block);
>>>>>     unsafe_put_user(&frame->uc, &frame->puc, badframe_block);
>>>>>     ...
>>>>>     if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
>>>>>         err |= get_user(regs->gpr[4], (unsigned long __user *)&frame->pinfo);
>>>>>         err |= get_user(regs->gpr[5], (unsigned long __user *)&frame->puc);
>>>>>
>>>>> ie. we write &frame->info into frame->pinfo, and then read frame->pinfo
>>>>> back into r4, and similarly for &frame->uc.
>>>>>
>>>>> The code has always been like this, since linux-fullhistory commit
>>>>> d4f2d95eca2c ("Forward port of 2.4 ppc64 signal changes.").
>>>>>
>>>>> There's no reason for us to read the values back from user memory,
>>>>> rather than just setting the value in the gpr[4/5] directly. In fact
>>>>> reading the value back from user memory opens up the possibility of
>>>>> another user thread changing the values before we read them back.
>>>>> Although any process doing that would be racing against the kernel
>>>>> delivering the signal, and would risk corrupting the stack, so that
>>>>> would be a userspace bug.
>>>>>
>>>>> Note that this is 64-bit only code, so there's no subtlety with the size
>>>>> of pointers differing between kernel and user. Also the frame variable
>>>>> is not modified to point elsewhere during the function.
>>>>>
>>>>> In the past reading the values back from user memory was not costly, but
>>>>> now that we have KUAP on some CPUs it is, so we'd rather avoid it for
>>>>> that reason too.
>>>>>
>>>>> So change the code to just set the values directly, using the same
>>>>> values we have written to the sigframe previously in the function.
>>>>>
>>>>> Note also that this matches what our 32-bit signal code does.
>>>>>
>>>>> Using a version of will-it-scale's signal1_threads that sets SA_SIGINFO,
>>>>> this results in a ~4% increase in signals per second on a Power9, from
>>>>> 229,777 to 239,766.
>>>>
>>>> Good find, nice improvement. Will make it possible to make the error
>>>> handling much nicer too I think.
>>>>
>>>> Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
>>>>
>>>> You've moved copy_siginfo_to_user right up to the user access unlock,
>>>> could save 2 more KUAP lock/unlocks if we had an unsafe_clear_user. If
>>>> we can move the other user access stuff up as well, the stack frame
>>>> put_user could use unsafe_put_user as well, saving 1 more. Another few
>>>> percent?
>>>
>>> I'm looking at making an 'unsafe' version of copy_siginfo_to_user().
>>> That's straight forward for 'native' signals, but for compat signals that's more tricky.
>>
>> Ah nice. Native is most important at the moment.
>>
> 
> Finally not so easy. We have a quite efficient clear_user() which uses 'dcbz'. When replacing that 
> by a simplistic unsafe_clear_user() on the same model as unsafe_copy_to_user(), performance are 
> degradated on 32s. Need to implement it more efficiently.
> 

Don't know what I did yesterday. Performance is _not_ degraded, it is improved by 5%. I'll send out 
a series soon.

  reply	other threads:[~2021-06-15  6:22 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-10  7:29 [PATCH] powerpc/signal64: Don't read sigaction arguments back from user memory Michael Ellerman
2021-06-14  1:32 ` Nicholas Piggin
2021-06-14  5:30   ` Christophe Leroy
2021-06-14  5:49     ` Nicholas Piggin
2021-06-14 11:49       ` Christophe Leroy
2021-06-15  6:22         ` Christophe Leroy [this message]
2021-06-18  3:51 ` Michael Ellerman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e01caafd-e96d-b31b-8983-4c0a9d285fc8@csgroup.eu \
    --to=christophe.leroy@csgroup.eu \
    --cc=cmr@codefail.de \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mpe@ellerman.id.au \
    --cc=npiggin@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox