m68k/uaccess: Fix asm constraints for userspace access
authorGeert Uytterhoeven <geert@linux-m68k.org>
Sun, 9 Jun 2013 18:12:42 +0000 (20:12 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 27 Oct 2015 00:44:49 +0000 (09:44 +0900)
commit 631d8b674f5f8235e9cb7e628b0fe9e5200e3158 upstream.

When compiling a MMU kernel with CPU_HAS_ADDRESS_SPACES=n (e.g. "MMU=y
allnoconfig": "echo CONFIG_MMU=y > allno.config && make KCONFIG_ALLCONFIG=1
allnoconfig"), we use plain "move" instead of "moves", and I got:

  CC      arch/m68k/lib/uaccess.o
{standard input}: Assembler messages:
{standard input}:47: Error: operands mismatch -- statement `move.b %a0,(%a1)' ignored

This happens because plain "move" doesn't support byte transfers between
memory and address registers, while "moves" does.

Fix the asm constraints for __generic_copy_from_user(),
__generic_copy_to_user(), and __clear_user() to only use data registers
when accessing userspace.

Also, relax the asm constraints for 16-bit userspace accesses in
__put_user() and __get_user(), as both "move" and "moves" do support
such transfers between memory and address registers.

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/m68k/include/asm/uaccess_mm.h
arch/m68k/lib/uaccess.c

index 472c891a4aeee4c1f1bc095b2e33b08840c5a6c2..15901db435b90675dd5ab9f931dc331632c04705 100644 (file)
@@ -90,7 +90,7 @@ asm volatile ("\n"                                    \
                __put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT); \
                break;                                                  \
        case 2:                                                         \
-               __put_user_asm(__pu_err, __pu_val, ptr, w, d, -EFAULT); \
+               __put_user_asm(__pu_err, __pu_val, ptr, w, r, -EFAULT); \
                break;                                                  \
        case 4:                                                         \
                __put_user_asm(__pu_err, __pu_val, ptr, l, r, -EFAULT); \
@@ -158,7 +158,7 @@ asm volatile ("\n"                                  \
                __get_user_asm(__gu_err, x, ptr, u8, b, d, -EFAULT);    \
                break;                                                  \
        case 2:                                                         \
-               __get_user_asm(__gu_err, x, ptr, u16, w, d, -EFAULT);   \
+               __get_user_asm(__gu_err, x, ptr, u16, w, r, -EFAULT);   \
                break;                                                  \
        case 4:                                                         \
                __get_user_asm(__gu_err, x, ptr, u32, l, r, -EFAULT);   \
@@ -245,7 +245,7 @@ __constant_copy_from_user(void *to, const void __user *from, unsigned long n)
                __get_user_asm(res, *(u8 *)to, (u8 __user *)from, u8, b, d, 1);
                break;
        case 2:
-               __get_user_asm(res, *(u16 *)to, (u16 __user *)from, u16, w, d, 2);
+               __get_user_asm(res, *(u16 *)to, (u16 __user *)from, u16, w, r, 2);
                break;
        case 3:
                __constant_copy_from_user_asm(res, to, from, tmp, 3, w, b,);
@@ -326,7 +326,7 @@ __constant_copy_to_user(void __user *to, const void *from, unsigned long n)
                __put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1);
                break;
        case 2:
-               __put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, d, 2);
+               __put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, r, 2);
                break;
        case 3:
                __constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,);
index 5e97f2ee7c1197feaf1fb79ec07cd10566466026..35d1442dee899af023a2e801401f8dc319272779 100644 (file)
@@ -52,7 +52,7 @@ unsigned long __generic_copy_from_user(void *to, const void __user *from,
                "       .long   3b,30b\n"
                "       .long   5b,50b\n"
                "       .previous"
-               : "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
+               : "=d" (res), "+a" (from), "+a" (to), "=&d" (tmp)
                : "0" (n / 4), "d" (n & 3));
 
        return res;
@@ -96,7 +96,7 @@ unsigned long __generic_copy_to_user(void __user *to, const void *from,
                "       .long   7b,50b\n"
                "       .long   8b,50b\n"
                "       .previous"
-               : "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
+               : "=d" (res), "+a" (from), "+a" (to), "=&d" (tmp)
                : "0" (n / 4), "d" (n & 3));
 
        return res;
@@ -141,7 +141,7 @@ unsigned long __clear_user(void __user *to, unsigned long n)
                "       .long   7b,40b\n"
                "       .previous"
                : "=d" (res), "+a" (to)
-               : "r" (0), "0" (n / 4), "d" (n & 3));
+               : "d" (0), "0" (n / 4), "d" (n & 3));
 
     return res;
 }