Re: [tip:x86/mm] x86, mm: Redesign get_user with a __builtin_choose_expr hack
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
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
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
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
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
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
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
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
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
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
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
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/