From: Thiago Jung Bauermann <bauerman@linux.ibm.com>
To: Gabriel Paubert <paubert@iram.es>
Cc: Ram Pai <linuxram@us.ibm.com>,
fweimer@redhat.com, mhocko@kernel.org, Ulrich.Weigand@de.ibm.com,
bauerman@linux.vnet.ibm.com, msuchanek@suse.de,
linuxppc-dev@lists.ozlabs.org
Subject: Re: [PATCH 1/2] powerpc/pkeys: preallocate execute_only key only if the key is available.
Date: Fri, 29 Jun 2018 21:58:37 -0300 [thread overview]
Message-ID: <8736x5yts2.fsf@morokweng.localdomain> (raw)
In-Reply-To: <20180629060715.36xlai5mayyx6j34@lt-gp.iram.es>
Gabriel Paubert <paubert@iram.es> writes:
> On Thu, Jun 28, 2018 at 11:56:34PM -0300, Thiago Jung Bauermann wrote:
>>
>> Hello,
>>
>> Ram Pai <linuxram@us.ibm.com> writes:
>>
>> > Key 2 is preallocated and reserved for execute-only key. In rare
>> > cases if key-2 is unavailable, mprotect(PROT_EXEC) will behave
>> > incorrectly. NOTE: mprotect(PROT_EXEC) uses execute-only key.
>> >
>> > Ensure key 2 is available for preallocation before reserving it for
>> > execute_only purpose. Problem noticed by Michael Ellermen.
>>
>> Since "powerpc/pkeys: Preallocate execute-only key" isn't upstream yet,
>> this patch could be squashed into it.
>>
>> > Signed-off-by: Ram Pai <linuxram@us.ibm.com>
>> > ---
>> > arch/powerpc/mm/pkeys.c | 14 +++++++++-----
>> > 1 files changed, 9 insertions(+), 5 deletions(-)
>> >
>> > diff --git a/arch/powerpc/mm/pkeys.c b/arch/powerpc/mm/pkeys.c
>> > index cec990c..0b03914 100644
>> > --- a/arch/powerpc/mm/pkeys.c
>> > +++ b/arch/powerpc/mm/pkeys.c
>> > @@ -19,6 +19,7 @@
>> > u64 pkey_amr_mask; /* Bits in AMR not to be touched */
>> > u64 pkey_iamr_mask; /* Bits in AMR not to be touched */
>> > u64 pkey_uamor_mask; /* Bits in UMOR not to be touched */
>> > +int execute_only_key = 2;
>> >
>> > #define AMR_BITS_PER_PKEY 2
>> > #define AMR_RD_BIT 0x1UL
>> > @@ -26,7 +27,6 @@
>> > #define IAMR_EX_BIT 0x1UL
>> > #define PKEY_REG_BITS (sizeof(u64)*8)
>> > #define pkeyshift(pkey) (PKEY_REG_BITS - ((pkey+1) * AMR_BITS_PER_PKEY))
>> > -#define EXECUTE_ONLY_KEY 2
>> >
>> > static void scan_pkey_feature(void)
>> > {
>> > @@ -122,8 +122,12 @@ int pkey_initialize(void)
>> > #else
>> > os_reserved = 0;
>> > #endif
>> > +
>> > + if ((pkeys_total - os_reserved) <= execute_only_key)
>> > + execute_only_key = -1;
>> > +
>> > /* Bits are in LE format. */
>> > - reserved_allocation_mask = (0x1 << 1) | (0x1 << EXECUTE_ONLY_KEY);
>> > + reserved_allocation_mask = (0x1 << 1) | (0x1 << execute_only_key);
>>
>> My understanding is that left-shifting by a negative amount is undefined
>> behavior in C. A quick test tells me that at least on the couple of
>> machines I tested, 1 < -1 = 0. Does GCC guarantee that behavior?
>
> Not in general. It probably always works on Power because of the definition
> of the machine instruction for shifts with variable amount (consider the
> shift amount unsigned and take it modulo twice the width of the operand),
Ok, thanks for confirming.
> but for example it fails on x86 (1<<-1 gives 0x80000000).
Strange, this works on my laptop with an Intel(R) Core(TM) i5-7300U CPU:
$ cat blah.c
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("1 << -1 = %llx\n", (unsigned long long) 1 << -1);
return 0;
}
$ make blah
cc blah.c -o blah
blah.c: In function 'main':
blah.c:5:52: warning: left shift count is negative [-Wshift-count-negative]
printf("1 << -1 = %llx\n", (unsigned long long) 1 << -1);
^~
$ ./blah
1 << -1 = 0
Even if I change the cast and printf format to int, the result is the
same. Or am I doing it wrong?
>> If so, a comment pointing this out would make this less confusing.
>
> Unless I miss something, this code is run once at boot, so its
> performance is irrelevant.
>
> In this case simply rewrite it as:
>
> reserved_allocation_mask = 0x1 << 1;
> if ( (pkeys_total - os_reserved) <= execute_only_key) {
> execute_only_key = -1;
> } else {
> reserved_allocation_mask = (0x1 << 1) | (0x1 << execute_only_key);
> }
I agree it's clearer and more robust code (except that the first
line should be inside the if block).
>
> Caveat, I have assumed that the code will either:
> - only run once,
> - pkeys_total and os_reserved are int, not unsigned
Both of the above are true.
--
Thiago Jung Bauermann
IBM Linux Technology Center
next prev parent reply other threads:[~2018-06-30 0:58 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-26 2:16 [PATCH 1/2] powerpc/pkeys: preallocate execute_only key only if the key is available Ram Pai
2018-06-26 2:16 ` [PATCH 2/2] powerpc/pkeys: key allocation/deallocation must not change pkey registers Ram Pai
2018-07-03 1:35 ` Thiago Jung Bauermann
2018-06-26 2:16 ` [PATCH 1/2] powerpc/core-pkeys: execute-permission on keys are disabled by default Ram Pai
2018-07-03 3:30 ` Thiago Jung Bauermann
2018-06-26 2:16 ` [PATCH 2/2] powerpc/ptrace-pkeys: " Ram Pai
2018-07-03 3:30 ` Thiago Jung Bauermann
2018-06-29 2:56 ` [PATCH 1/2] powerpc/pkeys: preallocate execute_only key only if the key is available Thiago Jung Bauermann
2018-06-29 6:07 ` Gabriel Paubert
2018-06-30 0:58 ` Thiago Jung Bauermann [this message]
2018-06-30 1:40 ` Ram Pai
2018-06-30 16:56 ` Gabriel Paubert
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=8736x5yts2.fsf@morokweng.localdomain \
--to=bauerman@linux.ibm.com \
--cc=Ulrich.Weigand@de.ibm.com \
--cc=bauerman@linux.vnet.ibm.com \
--cc=fweimer@redhat.com \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=linuxram@us.ibm.com \
--cc=mhocko@kernel.org \
--cc=msuchanek@suse.de \
--cc=paubert@iram.es \
/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