On Wed, 2 Nov 2005, David Daney wrote:
__get_user() is unhappy, with tpyes that are "const". It uses __typeof() to create a local variable that it wants to write to. I've intended tohave offer up a patch by now, but, too many unexpected thing have happened in the firs thalf of this week.
I shamed myself into sitting down and doing this. 8-) The attached patch seems to work, or at least doesn't seem to cause things to blow up. An o32 userspace on a 64-bit kernel comes up multi-user and can build a kernel, and run a quick subset of LTP. There was a comment on IRC that there was a register allocation issue which lead to the current code. I'm not sure of the exact details, but I _think_ this change ends up being equivilent to the code it replaces. Stuart Stuart R. Anderson anderson@xxxxxxxxxxxx Network & Software Engineering http://www.netsweng.com/ 1024D/37A79149: 0791 D3B8 9A4C 2CDC A31F BD03 0A62 E534 37A7 9149
Index: uaccess.h =================================================================== --- uaccess.h (revision 84) +++ uaccess.h (working copy) @@ -210,17 +210,35 @@ #define __get_user_nocheck(x,ptr,size) \ ({ \ - __typeof(*(ptr)) __gu_val = (__typeof(*(ptr))) 0; \ long __gu_err = 0; \ \ switch (size) { \ - case 1: __get_user_asm("lb", ptr); break; \ - case 2: __get_user_asm("lh", ptr); break; \ - case 4: __get_user_asm("lw", ptr); break; \ - case 8: __GET_USER_DW(ptr); break; \ + case 1: { \ + s8 __gu_val = (s8) 0; \ + __get_user_asm("lb", ptr); \ + (x) = (__typeof__(*(ptr))) __gu_val; \ + break; \ + } \ + case 2: { \ + s16 __gu_val = (s16) 0; \ + __get_user_asm("lh", ptr); \ + (x) = (__typeof__(*(ptr))) __gu_val; \ + break; \ + } \ + case 4: { \ + s32 __gu_val = (s32) 0; \ + __get_user_asm("lw", ptr); \ + (x) = (__typeof__(*(ptr))) __gu_val; \ + break; \ + } \ + case 8: { \ + s64 __gu_val = (s64) 0; \ + __GET_USER_DW(ptr); \ + (x) = (__typeof__(*(ptr))) __gu_val; \ + break; \ + } \ default: __get_user_unknown(); break; \ } \ - (x) = (__typeof__(*(ptr))) __gu_val; \ __gu_err; \ })