Re: [tip:x86/mm] x86, mm: Redesign get_user with a __builtin_choose_expr hack

2013-02-12 Thread H. Peter Anvin
On 02/12/2013 03:49 PM, Linus Torvalds wrote:
> On Tue, Feb 12, 2013 at 3:19 PM, H. Peter Anvin  wrote:
>>
>> Yes, but there doesn't seem to be any other way to do this.  gcc won't
>> even allow "=cd" even if we know the variable is 64 bits, even though
>> "=A" is documented to be equivalent to "=da".
> 
> No, "=da" means value "in edx _or_ %eax". Not the same as "A".
> 

Actually, if you look at how gcc implements them, they are the same, and
if you are luckless enough to try to use a 32-bit value with an "A"
constraint you have it end up in either %eax or %edx.

However, they seem to have added some additional linting which prohibits
the compound form.  I'm not sure it would have worked anyway since we
need the two-register bit to be conditional.

> But you're right, there's nothing similar for %ebx:%ecx. I thought
> there was. I was really sure we did something special for 64-bit adc
> etc.
> 
>> Let me know what you think.
> 
> I guess we don't have any choice. And the other cleanups certainly look good.

OK, will commit the comment.  We can add the additional copy if we need it.

-hpa


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


Re: [tip:x86/mm] x86, mm: Redesign get_user with a __builtin_choose_expr hack

2013-02-12 Thread Linus Torvalds
On Tue, Feb 12, 2013 at 3:19 PM, H. Peter Anvin  wrote:
>
> Yes, but there doesn't seem to be any other way to do this.  gcc won't
> even allow "=cd" even if we know the variable is 64 bits, even though
> "=A" is documented to be equivalent to "=da".

No, "=da" means value "in edx _or_ %eax". Not the same as "A".

But you're right, there's nothing similar for %ebx:%ecx. I thought
there was. I was really sure we did something special for 64-bit adc
etc.

> Let me know what you think.

I guess we don't have any choice. And the other cleanups certainly look good.

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


Re: [tip:x86/mm] x86, mm: Redesign get_user with a __builtin_choose_expr hack

2013-02-12 Thread Russell King - ARM Linux
On Tue, Feb 12, 2013 at 03:06:51PM -0800, Linus Torvalds wrote:
> So this looks clean, but I noticed something (that was true even of
> the old 64-bit accesses)
> 
> On Tue, Feb 12, 2013 at 12:55 PM, tip-bot for H. Peter Anvin
>  wrote:
> > +   register __inttype(*(ptr)) __val_gu asm("%edx");\
> 
> How does gcc even alllow this?
> 
> On x86-32, you cannot put a 64-bit value in %edx.
> 
> Where do the upper bits go? It clearly cannot be %edx:%eax, since we
> put the error value in %eax.

I can't talk for x86, but the ARM version is this:

register __inttype(*p) __r2 asm("r2");

r2 is only 32-bit, so you can ask the same question there.  The answer
is, it ends up in r3, the next register, as required by the compiler
ABI.  (64-bit values are always contained in a consecutive even, odd
register pair.)

> Also, come to think of it, we have tried the "named register
> variables" thing before, and it has resulted in problems with scope.
> In particular, two variables within the same scope and the same
> register have been problematic. And it *does* happen, when you have
> things like
> 
>/* copy_user */
>put_user(get_user(.., addr), addr2);
> 
> and then things go downhill.

Umm.  Why would you want to put_user() the error code from get_user() ?
That's just weird, don't we normally want to return the error code?

But yes, I can see that kind of thing causing problems - I'll check
what the behaviour is on ARM.  What we _do_ have is a bit of assembly
level checking which verifies that the arguments are passed in the
correct registers, so at least we get build errors should things go
wrong.  We haven't seen that though.

> Maybe we do not have these issues, but there are good reasons why
> we've tried very hard on x86 to avoid named register variables.

Unfortunately on ARM there's no other way to get close to specifying
registers for asm code. :(
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [tip:x86/mm] x86, mm: Redesign get_user with a __builtin_choose_expr hack

2013-02-12 Thread H. Peter Anvin
On 02/12/2013 03:06 PM, Linus Torvalds wrote:
> So this looks clean, but I noticed something (that was true even of
> the old 64-bit accesses)
> 
> On Tue, Feb 12, 2013 at 12:55 PM, tip-bot for H. Peter Anvin
>  wrote:
>> +   register __inttype(*(ptr)) __val_gu asm("%edx");\
> 
> How does gcc even alllow this?
> 
> On x86-32, you cannot put a 64-bit value in %edx.
> 
> Where do the upper bits go? It clearly cannot be %edx:%eax, since we
> put the error value in %eax.
> 
> So is the rule for x86-32 that naming "long long" register values
> names the first register, and the high bits go into the next one (I
> forget the crazy register numbering, I assume it's %ecx). Or what?
> This should have a comment.
> 

Yes, it goes into the next register in gcc's register numbering, which
is %ecx.  This works with the register variable because the named
register is treated as a starting point, whereas using "=d" is treated
as a singleton register set.

I'll add a comment.

gcc's register numbering isn't all that crazy, incidentally: the only
difference from the standard x86 register numbering is that %ecx and
%edx is swapped, so that the standard %edx:%eax and %ebx:%ecx register
pairs end up consecutive.  It isn't really gcc's fault that the x86
register numbering doesn't match its (hard-coded!) register conventions...

> Also, come to think of it, we have tried the "named register
> variables" thing before, and it has resulted in problems with scope.
> In particular, two variables within the same scope and the same
> register have been problematic. And it *does* happen, when you have
> things like
> 
>/* copy_user */
>put_user(get_user(.., addr), addr2);
> 
> and then things go downhill.
> 
> Maybe we do not have these issues, but there are good reasons why
> we've tried very hard on x86 to avoid named register variables.

Yes, but there doesn't seem to be any other way to do this.  gcc won't
even allow "=cd" even if we know the variable is 64 bits, even though
"=A" is documented to be equivalent to "=da".

I don't think we have any additional problem here,though.  If we are
inside a scope with "%edx" as a named register variable *and* that
variable is live at the point get_user() happens, then yes, we can and
will have a problem, regardless if we use "=d" or a named register
variable.  The only solution to that is to keep the named register
variable live for as short time as possible.

If we do run into trouble, we could introduce a second copy, thus
reducing the lifespan of the named variable to the absolute minimum:

register __inttype(*(ptr)) __val_gu asm("%edx");
__inttype(*(ptr)) __val_gv;

asm volatile(...);

__val_gv = __val_gu;
(x) = (__typeof__(*(ptr))) __val_gv;

That way if the evaluation of (x) as an lvalue somehow requires specific
registers they don't collide.

I would prefer if we could worry about that when we actually need to,
though.  It will trigger a compile error if relevant, so it shouldn't
cause any risk of silent corruption.

> (I realize that they happen, and some other architectures don't even
> have good support for naming registers any other way so they are way
> more common there, so I probably worry needlessly, but it does worry
> me).

Let me know what you think.

-hpa

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


Re: [tip:x86/mm] x86, mm: Redesign get_user with a __builtin_choose_expr hack

2013-02-12 Thread Linus Torvalds
So this looks clean, but I noticed something (that was true even of
the old 64-bit accesses)

On Tue, Feb 12, 2013 at 12:55 PM, tip-bot for H. Peter Anvin
 wrote:
> +   register __inttype(*(ptr)) __val_gu asm("%edx");\

How does gcc even alllow this?

On x86-32, you cannot put a 64-bit value in %edx.

Where do the upper bits go? It clearly cannot be %edx:%eax, since we
put the error value in %eax.

So is the rule for x86-32 that naming "long long" register values
names the first register, and the high bits go into the next one (I
forget the crazy register numbering, I assume it's %ecx). Or what?
This should have a comment.

Also, come to think of it, we have tried the "named register
variables" thing before, and it has resulted in problems with scope.
In particular, two variables within the same scope and the same
register have been problematic. And it *does* happen, when you have
things like

   /* copy_user */
   put_user(get_user(.., addr), addr2);

and then things go downhill.

Maybe we do not have these issues, but there are good reasons why
we've tried very hard on x86 to avoid named register variables.

(I realize that they happen, and some other architectures don't even
have good support for naming registers any other way so they are way
more common there, so I probably worry needlessly, but it does worry
me).

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


[tip:x86/mm] x86, mm: Redesign get_user with a __builtin_choose_expr hack

2013-02-12 Thread tip-bot for H. Peter Anvin
Commit-ID:  3578baaed4613a9fc09bab9f79f6ce2ac682e8a3
Gitweb: http://git.kernel.org/tip/3578baaed4613a9fc09bab9f79f6ce2ac682e8a3
Author: H. Peter Anvin 
AuthorDate: Tue, 12 Feb 2013 11:47:31 -0800
Committer:  H. Peter Anvin 
CommitDate: Tue, 12 Feb 2013 12:46:40 -0800

x86, mm: Redesign get_user with a __builtin_choose_expr hack

Instead of using a bitfield, use an odd little trick using typeof,
__builtin_choose_expr, and sizeof.  __builtin_choose_expr is
explicitly defined to not convert its type (its argument is required
to be a constant expression) so this should be well-defined.

The code is still not 100% preturbation-free versus the baseline
before 64-bit get_user(), but the differences seem to be very small,
mostly related to padding and to gcc deciding when to spill registers.

Cc: Jamie Lokier 
Cc: Ville Syrjälä 
Cc: Borislav Petkov 
Cc: Russell King 
Cc: Linus Torvalds 
Cc: H. J. Lu 
Link: http://lkml.kernel.org/r/511a8922.6050...@zytor.com
Signed-off-by: H. Peter Anvin 
---
 arch/x86/include/asm/uaccess.h | 57 +++---
 1 file changed, 14 insertions(+), 43 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index a8d1265..d710a25 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -125,13 +125,12 @@ extern int __get_user_4(void);
 extern int __get_user_8(void);
 extern int __get_user_bad(void);
 
-#define __get_user_x(size, ret, x, ptr)  \
-   asm volatile("call __get_user_" #size \
-: "=a" (ret), "=d" (x)   \
-: "0" (ptr)) \
-
-/* Careful: we have to cast the result to the type of the pointer
- * for sign reasons */
+/*
+ * This is a type: either unsigned long, if the argument fits into
+ * that type, or otherwise unsigned long long.
+ */
+#define __inttype(x) \
+__typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
 
 /**
  * get_user: - Get a simple variable from user space.
@@ -149,48 +148,20 @@ extern int __get_user_bad(void);
  *
  * Returns zero on success, or -EFAULT on error.
  * On error, the variable @x is set to zero.
+ *
+ * Careful: we have to cast the result to the type of the pointer
+ * for sign reasons.
  */
-#ifdef CONFIG_X86_32
-#define __get_user_8(ret, x, ptr)\
-do { \
-   register unsigned long long __xx asm("%edx"); \
-   asm volatile("call __get_user_8"  \
-: "=a" (ret), "=r" (__xx)\
-: "0" (ptr));\
-   (x) = __xx;   \
-} while (0)
-
-#else
-#define __get_user_8(__ret_gu, __val_gu, ptr)  \
-   __get_user_x(8, __ret_gu, __val_gu, ptr)
-#endif
-
 #define get_user(x, ptr)   \
 ({ \
int __ret_gu;   \
-   struct {\
-   unsigned long long __val_n : 8*sizeof(*(ptr));  \
-   } __val_gu; \
+   register __inttype(*(ptr)) __val_gu asm("%edx");\
__chk_user_ptr(ptr);\
might_fault();  \
-   switch (sizeof(*(ptr))) {   \
-   case 1: \
-   __get_user_x(1, __ret_gu, __val_gu.__val_n, ptr);   \
-   break;  \
-   case 2: \
-   __get_user_x(2, __ret_gu, __val_gu.__val_n, ptr);   \
-   break;  \
-   case 4: \
-   __get_user_x(4, __ret_gu, __val_gu.__val_n, ptr);   \
-   break;  \
-   case 8: \
-   __get_user_8(__ret_gu, __val_gu.__val_n, ptr);  \
-   break;  \
-   default:\
-   __get_user_x(X, __ret_gu, __val_gu.__val_n, ptr);   \
-   break;  \
-   }   \
-   (x) = (__typeof__(*(ptr)))__val_gu.__val_n; \
+   asm volatile("call __get_user_%P3"  \
+: "=a" (__ret_gu), "=r" 

[tip:x86/mm] x86, mm: Redesign get_user with a __builtin_choose_expr hack

2013-02-12 Thread tip-bot for H. Peter Anvin
Commit-ID:  3578baaed4613a9fc09bab9f79f6ce2ac682e8a3
Gitweb: http://git.kernel.org/tip/3578baaed4613a9fc09bab9f79f6ce2ac682e8a3
Author: H. Peter Anvin h...@linux.intel.com
AuthorDate: Tue, 12 Feb 2013 11:47:31 -0800
Committer:  H. Peter Anvin h...@linux.intel.com
CommitDate: Tue, 12 Feb 2013 12:46:40 -0800

x86, mm: Redesign get_user with a __builtin_choose_expr hack

Instead of using a bitfield, use an odd little trick using typeof,
__builtin_choose_expr, and sizeof.  __builtin_choose_expr is
explicitly defined to not convert its type (its argument is required
to be a constant expression) so this should be well-defined.

The code is still not 100% preturbation-free versus the baseline
before 64-bit get_user(), but the differences seem to be very small,
mostly related to padding and to gcc deciding when to spill registers.

Cc: Jamie Lokier ja...@shareable.org
Cc: Ville Syrjälä ville.syrj...@linux.intel.com
Cc: Borislav Petkov b...@alien8.de
Cc: Russell King li...@arm.linux.org.uk
Cc: Linus Torvalds torva...@linux-foundation.org
Cc: H. J. Lu hjl.to...@gmail.com
Link: http://lkml.kernel.org/r/511a8922.6050...@zytor.com
Signed-off-by: H. Peter Anvin h...@linux.intel.com
---
 arch/x86/include/asm/uaccess.h | 57 +++---
 1 file changed, 14 insertions(+), 43 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index a8d1265..d710a25 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -125,13 +125,12 @@ extern int __get_user_4(void);
 extern int __get_user_8(void);
 extern int __get_user_bad(void);
 
-#define __get_user_x(size, ret, x, ptr)  \
-   asm volatile(call __get_user_ #size \
-: =a (ret), =d (x)   \
-: 0 (ptr)) \
-
-/* Careful: we have to cast the result to the type of the pointer
- * for sign reasons */
+/*
+ * This is a type: either unsigned long, if the argument fits into
+ * that type, or otherwise unsigned long long.
+ */
+#define __inttype(x) \
+__typeof__(__builtin_choose_expr(sizeof(x)  sizeof(0UL), 0ULL, 0UL))
 
 /**
  * get_user: - Get a simple variable from user space.
@@ -149,48 +148,20 @@ extern int __get_user_bad(void);
  *
  * Returns zero on success, or -EFAULT on error.
  * On error, the variable @x is set to zero.
+ *
+ * Careful: we have to cast the result to the type of the pointer
+ * for sign reasons.
  */
-#ifdef CONFIG_X86_32
-#define __get_user_8(ret, x, ptr)\
-do { \
-   register unsigned long long __xx asm(%edx); \
-   asm volatile(call __get_user_8  \
-: =a (ret), =r (__xx)\
-: 0 (ptr));\
-   (x) = __xx;   \
-} while (0)
-
-#else
-#define __get_user_8(__ret_gu, __val_gu, ptr)  \
-   __get_user_x(8, __ret_gu, __val_gu, ptr)
-#endif
-
 #define get_user(x, ptr)   \
 ({ \
int __ret_gu;   \
-   struct {\
-   unsigned long long __val_n : 8*sizeof(*(ptr));  \
-   } __val_gu; \
+   register __inttype(*(ptr)) __val_gu asm(%edx);\
__chk_user_ptr(ptr);\
might_fault();  \
-   switch (sizeof(*(ptr))) {   \
-   case 1: \
-   __get_user_x(1, __ret_gu, __val_gu.__val_n, ptr);   \
-   break;  \
-   case 2: \
-   __get_user_x(2, __ret_gu, __val_gu.__val_n, ptr);   \
-   break;  \
-   case 4: \
-   __get_user_x(4, __ret_gu, __val_gu.__val_n, ptr);   \
-   break;  \
-   case 8: \
-   __get_user_8(__ret_gu, __val_gu.__val_n, ptr);  \
-   break;  \
-   default:\
-   __get_user_x(X, __ret_gu, __val_gu.__val_n, ptr);   \
-   break;  \
-   }   \
-   (x) = 

Re: [tip:x86/mm] x86, mm: Redesign get_user with a __builtin_choose_expr hack

2013-02-12 Thread Linus Torvalds
So this looks clean, but I noticed something (that was true even of
the old 64-bit accesses)

On Tue, Feb 12, 2013 at 12:55 PM, tip-bot for H. Peter Anvin
h...@linux.intel.com wrote:
 +   register __inttype(*(ptr)) __val_gu asm(%edx);\

How does gcc even alllow this?

On x86-32, you cannot put a 64-bit value in %edx.

Where do the upper bits go? It clearly cannot be %edx:%eax, since we
put the error value in %eax.

So is the rule for x86-32 that naming long long register values
names the first register, and the high bits go into the next one (I
forget the crazy register numbering, I assume it's %ecx). Or what?
This should have a comment.

Also, come to think of it, we have tried the named register
variables thing before, and it has resulted in problems with scope.
In particular, two variables within the same scope and the same
register have been problematic. And it *does* happen, when you have
things like

   /* copy_user */
   put_user(get_user(.., addr), addr2);

and then things go downhill.

Maybe we do not have these issues, but there are good reasons why
we've tried very hard on x86 to avoid named register variables.

(I realize that they happen, and some other architectures don't even
have good support for naming registers any other way so they are way
more common there, so I probably worry needlessly, but it does worry
me).

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


Re: [tip:x86/mm] x86, mm: Redesign get_user with a __builtin_choose_expr hack

2013-02-12 Thread H. Peter Anvin
On 02/12/2013 03:06 PM, Linus Torvalds wrote:
 So this looks clean, but I noticed something (that was true even of
 the old 64-bit accesses)
 
 On Tue, Feb 12, 2013 at 12:55 PM, tip-bot for H. Peter Anvin
 h...@linux.intel.com wrote:
 +   register __inttype(*(ptr)) __val_gu asm(%edx);\
 
 How does gcc even alllow this?
 
 On x86-32, you cannot put a 64-bit value in %edx.
 
 Where do the upper bits go? It clearly cannot be %edx:%eax, since we
 put the error value in %eax.
 
 So is the rule for x86-32 that naming long long register values
 names the first register, and the high bits go into the next one (I
 forget the crazy register numbering, I assume it's %ecx). Or what?
 This should have a comment.
 

Yes, it goes into the next register in gcc's register numbering, which
is %ecx.  This works with the register variable because the named
register is treated as a starting point, whereas using =d is treated
as a singleton register set.

I'll add a comment.

gcc's register numbering isn't all that crazy, incidentally: the only
difference from the standard x86 register numbering is that %ecx and
%edx is swapped, so that the standard %edx:%eax and %ebx:%ecx register
pairs end up consecutive.  It isn't really gcc's fault that the x86
register numbering doesn't match its (hard-coded!) register conventions...

 Also, come to think of it, we have tried the named register
 variables thing before, and it has resulted in problems with scope.
 In particular, two variables within the same scope and the same
 register have been problematic. And it *does* happen, when you have
 things like
 
/* copy_user */
put_user(get_user(.., addr), addr2);
 
 and then things go downhill.
 
 Maybe we do not have these issues, but there are good reasons why
 we've tried very hard on x86 to avoid named register variables.

Yes, but there doesn't seem to be any other way to do this.  gcc won't
even allow =cd even if we know the variable is 64 bits, even though
=A is documented to be equivalent to =da.

I don't think we have any additional problem here,though.  If we are
inside a scope with %edx as a named register variable *and* that
variable is live at the point get_user() happens, then yes, we can and
will have a problem, regardless if we use =d or a named register
variable.  The only solution to that is to keep the named register
variable live for as short time as possible.

If we do run into trouble, we could introduce a second copy, thus
reducing the lifespan of the named variable to the absolute minimum:

register __inttype(*(ptr)) __val_gu asm(%edx);
__inttype(*(ptr)) __val_gv;

asm volatile(...);

__val_gv = __val_gu;
(x) = (__typeof__(*(ptr))) __val_gv;

That way if the evaluation of (x) as an lvalue somehow requires specific
registers they don't collide.

I would prefer if we could worry about that when we actually need to,
though.  It will trigger a compile error if relevant, so it shouldn't
cause any risk of silent corruption.

 (I realize that they happen, and some other architectures don't even
 have good support for naming registers any other way so they are way
 more common there, so I probably worry needlessly, but it does worry
 me).

Let me know what you think.

-hpa

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


Re: [tip:x86/mm] x86, mm: Redesign get_user with a __builtin_choose_expr hack

2013-02-12 Thread Russell King - ARM Linux
On Tue, Feb 12, 2013 at 03:06:51PM -0800, Linus Torvalds wrote:
 So this looks clean, but I noticed something (that was true even of
 the old 64-bit accesses)
 
 On Tue, Feb 12, 2013 at 12:55 PM, tip-bot for H. Peter Anvin
 h...@linux.intel.com wrote:
  +   register __inttype(*(ptr)) __val_gu asm(%edx);\
 
 How does gcc even alllow this?
 
 On x86-32, you cannot put a 64-bit value in %edx.
 
 Where do the upper bits go? It clearly cannot be %edx:%eax, since we
 put the error value in %eax.

I can't talk for x86, but the ARM version is this:

register __inttype(*p) __r2 asm(r2);

r2 is only 32-bit, so you can ask the same question there.  The answer
is, it ends up in r3, the next register, as required by the compiler
ABI.  (64-bit values are always contained in a consecutive even, odd
register pair.)

 Also, come to think of it, we have tried the named register
 variables thing before, and it has resulted in problems with scope.
 In particular, two variables within the same scope and the same
 register have been problematic. And it *does* happen, when you have
 things like
 
/* copy_user */
put_user(get_user(.., addr), addr2);
 
 and then things go downhill.

Umm.  Why would you want to put_user() the error code from get_user() ?
That's just weird, don't we normally want to return the error code?

But yes, I can see that kind of thing causing problems - I'll check
what the behaviour is on ARM.  What we _do_ have is a bit of assembly
level checking which verifies that the arguments are passed in the
correct registers, so at least we get build errors should things go
wrong.  We haven't seen that though.

 Maybe we do not have these issues, but there are good reasons why
 we've tried very hard on x86 to avoid named register variables.

Unfortunately on ARM there's no other way to get close to specifying
registers for asm code. :(
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [tip:x86/mm] x86, mm: Redesign get_user with a __builtin_choose_expr hack

2013-02-12 Thread Linus Torvalds
On Tue, Feb 12, 2013 at 3:19 PM, H. Peter Anvin h...@zytor.com wrote:

 Yes, but there doesn't seem to be any other way to do this.  gcc won't
 even allow =cd even if we know the variable is 64 bits, even though
 =A is documented to be equivalent to =da.

No, =da means value in edx _or_ %eax. Not the same as A.

But you're right, there's nothing similar for %ebx:%ecx. I thought
there was. I was really sure we did something special for 64-bit adc
etc.

 Let me know what you think.

I guess we don't have any choice. And the other cleanups certainly look good.

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


Re: [tip:x86/mm] x86, mm: Redesign get_user with a __builtin_choose_expr hack

2013-02-12 Thread H. Peter Anvin
On 02/12/2013 03:49 PM, Linus Torvalds wrote:
 On Tue, Feb 12, 2013 at 3:19 PM, H. Peter Anvin h...@zytor.com wrote:

 Yes, but there doesn't seem to be any other way to do this.  gcc won't
 even allow =cd even if we know the variable is 64 bits, even though
 =A is documented to be equivalent to =da.
 
 No, =da means value in edx _or_ %eax. Not the same as A.
 

Actually, if you look at how gcc implements them, they are the same, and
if you are luckless enough to try to use a 32-bit value with an A
constraint you have it end up in either %eax or %edx.

However, they seem to have added some additional linting which prohibits
the compound form.  I'm not sure it would have worked anyway since we
need the two-register bit to be conditional.

 But you're right, there's nothing similar for %ebx:%ecx. I thought
 there was. I was really sure we did something special for 64-bit adc
 etc.
 
 Let me know what you think.
 
 I guess we don't have any choice. And the other cleanups certainly look good.

OK, will commit the comment.  We can add the additional copy if we need it.

-hpa


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