m68k/uaccess: Fix asm constraints for userspace access
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>
This commit is contained in:
@@ -90,7 +90,7 @@ asm volatile ("\n" \
|
|||||||
__put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT); \
|
__put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT); \
|
||||||
break; \
|
break; \
|
||||||
case 2: \
|
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; \
|
break; \
|
||||||
case 4: \
|
case 4: \
|
||||||
__put_user_asm(__pu_err, __pu_val, ptr, l, r, -EFAULT); \
|
__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); \
|
__get_user_asm(__gu_err, x, ptr, u8, b, d, -EFAULT); \
|
||||||
break; \
|
break; \
|
||||||
case 2: \
|
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; \
|
break; \
|
||||||
case 4: \
|
case 4: \
|
||||||
__get_user_asm(__gu_err, x, ptr, u32, l, r, -EFAULT); \
|
__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);
|
__get_user_asm(res, *(u8 *)to, (u8 __user *)from, u8, b, d, 1);
|
||||||
break;
|
break;
|
||||||
case 2:
|
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;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
__constant_copy_from_user_asm(res, to, from, tmp, 3, w, b,);
|
__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);
|
__put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1);
|
||||||
break;
|
break;
|
||||||
case 2:
|
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;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
__constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,);
|
__constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,);
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ unsigned long __generic_copy_from_user(void *to, const void __user *from,
|
|||||||
" .long 3b,30b\n"
|
" .long 3b,30b\n"
|
||||||
" .long 5b,50b\n"
|
" .long 5b,50b\n"
|
||||||
" .previous"
|
" .previous"
|
||||||
: "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
|
: "=d" (res), "+a" (from), "+a" (to), "=&d" (tmp)
|
||||||
: "0" (n / 4), "d" (n & 3));
|
: "0" (n / 4), "d" (n & 3));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -96,7 +96,7 @@ unsigned long __generic_copy_to_user(void __user *to, const void *from,
|
|||||||
" .long 7b,50b\n"
|
" .long 7b,50b\n"
|
||||||
" .long 8b,50b\n"
|
" .long 8b,50b\n"
|
||||||
" .previous"
|
" .previous"
|
||||||
: "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
|
: "=d" (res), "+a" (from), "+a" (to), "=&d" (tmp)
|
||||||
: "0" (n / 4), "d" (n & 3));
|
: "0" (n / 4), "d" (n & 3));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -141,7 +141,7 @@ unsigned long __clear_user(void __user *to, unsigned long n)
|
|||||||
" .long 7b,40b\n"
|
" .long 7b,40b\n"
|
||||||
" .previous"
|
" .previous"
|
||||||
: "=d" (res), "+a" (to)
|
: "=d" (res), "+a" (to)
|
||||||
: "r" (0), "0" (n / 4), "d" (n & 3));
|
: "d" (0), "0" (n / 4), "d" (n & 3));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user