From: daniel.thompson@linaro.org (Daniel Thompson)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3] ARM: add get_user() support for 8 byte types
Date: Tue, 17 Jun 2014 11:17:23 +0100 [thread overview]
Message-ID: <53A015B3.2070809@linaro.org> (raw)
In-Reply-To: <20140612155843.GK23430@n2100.arm.linux.org.uk>
On 12/06/14 16:58, Russell King - ARM Linux wrote:
> On Thu, Jun 12, 2014 at 04:42:35PM +0100, Daniel Thompson wrote:
>> A new atomic modeset/pageflip ioctl being developed in DRM requires
>> get_user() to work for 64bit types (in addition to just put_user()).
>>
>> v1: original
>> v2: pass correct size to check_uaccess, and better handling of narrowing
>> double word read with __get_user_xb() (Russell King's suggestion)
>> v3: fix a couple of checkpatch issues
>
> This is still unsafe.
>
>> #define __get_user_check(x,p) \
>> ({ \
>> unsigned long __limit = current_thread_info()->addr_limit - 1; \
>> register const typeof(*(p)) __user *__p asm("r0") = (p);\
>> - register unsigned long __r2 asm("r2"); \
>> + register typeof(x) __r2 asm("r2"); \
>
> So, __r2 becomes the type of 'x'. If 'x' is a 64-bit type, and *p is
> an 8-bit, 16-bit, or 32-bit type, this fails horribly by leaving the
> upper word of __r2 undefined.
It is true that at after the switch statement the contents of r3 are
undefined. However...
> register unsigned long __l asm("r1") = __limit; \
> register int __e asm("r0"); \
> switch (sizeof(*(__p))) { \
> @@ -142,6 +152,12 @@ extern int __get_user_4(void *);
> case 4: \
> __get_user_x(__r2, __p, __e, __l, 4); \
> break; \
> + case 8: \
> + if (sizeof((x)) < 8) \
> + __get_user_xb(__r2, __p, __e, __l, 4);\
> + else \
> + __get_user_x(__r2, __p, __e, __l, 8);\
> + break; \
> default: __e = __get_user_bad(); break; \
> } \
> x = (typeof(*(p))) __r2; \
... at this point there is a narrowing cast followed by an implicit
widening. This results in compiler either ignoring r3 altogether or, if
spilling to the stack, generating code to set r3 to zero before doing
the store.
I think this approach also makes 8-bit and 16-bit get_user() faster in
some cases where the type of *p and x are similar 8- or 16-bit types.
This is because the compiler will never generate a redundant narrowings.
Note that the speed improvement looks extremely marginal; the size of
the .text section (for a multi_v7_defconfig kernel) only gets 96 bytes
smaller (a.k.a. 0.0015%).
Daniel.
next prev parent reply other threads:[~2014-06-17 10:17 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-12 15:42 [PATCH v3] ARM: add get_user() support for 8 byte types Daniel Thompson
2014-06-12 15:58 ` Russell King - ARM Linux
2014-06-17 10:17 ` Daniel Thompson [this message]
2014-06-17 11:09 ` Russell King - ARM Linux
2014-06-17 13:28 ` Daniel Thompson
2014-06-17 13:36 ` Russell King - ARM Linux
2014-06-17 13:54 ` Daniel Thompson
2014-06-12 17:04 ` Arnd Bergmann
2014-06-20 10:01 ` [PATCH v4] " Daniel Thompson
2014-07-10 19:47 ` [PATCH 3.16.0-rc3-rmk v5] " Daniel Thompson
2014-08-21 5:36 ` Victor Kamensky
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=53A015B3.2070809@linaro.org \
--to=daniel.thompson@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
/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;
as well as URLs for NNTP newsgroup(s).