^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef __M68K_UACCESS_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define __M68K_UACCESS_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #ifdef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * User space memory access functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/segment.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/extable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /* We let the MMU do all checking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) static inline int access_ok(const void __user *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Not all varients of the 68k family support the notion of address spaces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * The traditional 680x0 parts do, and they use the sfc/dfc registers and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * the "moves" instruction to access user space from kernel space. Other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * family members like ColdFire don't support this, and only have a single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * address space, and use the usual "move" instruction for user space access.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Outside of this difference the user space access functions are the same.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * So lets keep the code simple and just define in what we need to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #ifdef CONFIG_CPU_HAS_ADDRESS_SPACES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define MOVES "moves"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define MOVES "move"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) extern int __put_user_bad(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) extern int __get_user_bad(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define __put_user_asm(res, x, ptr, bwl, reg, err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) asm volatile ("\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) "1: "MOVES"."#bwl" %2,%1\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) "2:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) " .section .fixup,\"ax\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) " .even\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) "10: moveq.l %3,%0\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) " jra 2b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) " .previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) "\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) " .section __ex_table,\"a\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) " .align 4\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) " .long 1b,10b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) " .long 2b,10b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) " .previous" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) : "+d" (res), "=m" (*(ptr)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) : #reg (x), "i" (err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * These are the main single-value transfer routines. They automatically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * use the right size if we just have the right pointer type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define __put_user(x, ptr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) typeof(*(ptr)) __pu_val = (x); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int __pu_err = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) __chk_user_ptr(ptr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) switch (sizeof (*(ptr))) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) case 1: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) __put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) case 2: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) __put_user_asm(__pu_err, __pu_val, ptr, w, r, -EFAULT); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) case 4: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) __put_user_asm(__pu_err, __pu_val, ptr, l, r, -EFAULT); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) case 8: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) const void __user *__pu_ptr = (ptr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) asm volatile ("\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) "1: "MOVES".l %2,(%1)+\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) "2: "MOVES".l %R2,(%1)\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) "3:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) " .section .fixup,\"ax\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) " .even\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) "10: movel %3,%0\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) " jra 3b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) " .previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) "\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) " .section __ex_table,\"a\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) " .align 4\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) " .long 1b,10b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) " .long 2b,10b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) " .long 3b,10b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) " .previous" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) : "+d" (__pu_err), "+a" (__pu_ptr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) : "r" (__pu_val), "i" (-EFAULT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) : "memory"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) default: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) __pu_err = __put_user_bad(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) __pu_err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define put_user(x, ptr) __put_user(x, ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define __get_user_asm(res, x, ptr, type, bwl, reg, err) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) type __gu_val; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) asm volatile ("\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) "1: "MOVES"."#bwl" %2,%1\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) "2:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) " .section .fixup,\"ax\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) " .even\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) "10: move.l %3,%0\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) " sub.l %1,%1\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) " jra 2b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) " .previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) "\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) " .section __ex_table,\"a\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) " .align 4\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) " .long 1b,10b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) " .previous" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) : "+d" (res), "=&" #reg (__gu_val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) : "m" (*(ptr)), "i" (err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) (x) = (__force typeof(*(ptr)))(__force unsigned long)__gu_val; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define __get_user(x, ptr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int __gu_err = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) __chk_user_ptr(ptr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) switch (sizeof(*(ptr))) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) case 1: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) __get_user_asm(__gu_err, x, ptr, u8, b, d, -EFAULT); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) case 2: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) __get_user_asm(__gu_err, x, ptr, u16, w, r, -EFAULT); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) case 4: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) __get_user_asm(__gu_err, x, ptr, u32, l, r, -EFAULT); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case 8: { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) const void __user *__gu_ptr = (ptr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) union { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) u64 l; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) __typeof__(*(ptr)) t; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) } __gu_val; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) asm volatile ("\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) "1: "MOVES".l (%2)+,%1\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) "2: "MOVES".l (%2),%R1\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) "3:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) " .section .fixup,\"ax\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) " .even\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) "10: move.l %3,%0\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) " sub.l %1,%1\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) " sub.l %R1,%R1\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) " jra 3b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) " .previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) "\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) " .section __ex_table,\"a\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) " .align 4\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) " .long 1b,10b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) " .long 2b,10b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) " .previous" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) : "+d" (__gu_err), "=&r" (__gu_val.l), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) "+a" (__gu_ptr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) : "i" (-EFAULT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) : "memory"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) (x) = __gu_val.t; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) default: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) __gu_err = __get_user_bad(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) __gu_err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define get_user(x, ptr) __get_user(x, ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned long n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define __suffix0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define __suffix1 b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define __suffix2 w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define __suffix4 l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define ____constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) asm volatile ("\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) "1: "MOVES"."#s1" (%2)+,%3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) " move."#s1" %3,(%1)+\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) " .ifnc \""#s2"\",\"\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) "2: "MOVES"."#s2" (%2)+,%3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) " move."#s2" %3,(%1)+\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) " .ifnc \""#s3"\",\"\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) "3: "MOVES"."#s3" (%2)+,%3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) " move."#s3" %3,(%1)+\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) " .endif\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) " .endif\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) "4:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) " .section __ex_table,\"a\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) " .align 4\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) " .long 1b,10f\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) " .ifnc \""#s2"\",\"\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) " .long 2b,20f\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) " .ifnc \""#s3"\",\"\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) " .long 3b,30f\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) " .endif\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) " .endif\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) " .previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) "\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) " .section .fixup,\"ax\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) " .even\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) "10: addq.l #"#n1",%0\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) " .ifnc \""#s2"\",\"\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) "20: addq.l #"#n2",%0\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) " .ifnc \""#s3"\",\"\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) "30: addq.l #"#n3",%0\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) " .endif\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) " .endif\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) " jra 4b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) " .previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) : "+d" (res), "+&a" (to), "+a" (from), "=&d" (tmp) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) : : "memory")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #define ___constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) ____constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #define __constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) ___constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) __suffix##n1, __suffix##n2, __suffix##n3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static __always_inline unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) __constant_copy_from_user(void *to, const void __user *from, unsigned long n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) unsigned long res = 0, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) switch (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) __constant_copy_from_user_asm(res, to, from, tmp, 1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) __constant_copy_from_user_asm(res, to, from, tmp, 2, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) __constant_copy_from_user_asm(res, to, from, tmp, 2, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) __constant_copy_from_user_asm(res, to, from, tmp, 4, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) __constant_copy_from_user_asm(res, to, from, tmp, 4, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) __constant_copy_from_user_asm(res, to, from, tmp, 4, 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) __constant_copy_from_user_asm(res, to, from, tmp, 4, 2, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* we limit the inlined version to 3 moves */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return __generic_copy_from_user(to, from, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) asm volatile ("\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) " move."#s1" (%2)+,%3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) "11: "MOVES"."#s1" %3,(%1)+\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) "12: move."#s2" (%2)+,%3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) "21: "MOVES"."#s2" %3,(%1)+\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) "22:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) " .ifnc \""#s3"\",\"\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) " move."#s3" (%2)+,%3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) "31: "MOVES"."#s3" %3,(%1)+\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) "32:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) " .endif\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) "4:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) "\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) " .section __ex_table,\"a\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) " .align 4\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) " .long 11b,5f\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) " .long 12b,5f\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) " .long 21b,5f\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) " .long 22b,5f\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) " .ifnc \""#s3"\",\"\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) " .long 31b,5f\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) " .long 32b,5f\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) " .endif\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) " .previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) "\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) " .section .fixup,\"ax\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) " .even\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) "5: moveq.l #"#n",%0\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) " jra 4b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) " .previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) : "+d" (res), "+a" (to), "+a" (from), "=&d" (tmp) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) : : "memory")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static __always_inline unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) __constant_copy_to_user(void __user *to, const void *from, unsigned long n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) unsigned long res = 0, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) switch (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) __put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) __put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, r, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) __constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) __put_user_asm(res, *(u32 *)from, (u32 __user *)to, l, r, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) __constant_copy_to_user_asm(res, to, from, tmp, 5, l, b,);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) __constant_copy_to_user_asm(res, to, from, tmp, 6, l, w,);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) __constant_copy_to_user_asm(res, to, from, tmp, 7, l, w, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) __constant_copy_to_user_asm(res, to, from, tmp, 8, l, l,);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) __constant_copy_to_user_asm(res, to, from, tmp, 9, l, l, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) __constant_copy_to_user_asm(res, to, from, tmp, 10, l, l, w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) __constant_copy_to_user_asm(res, to, from, tmp, 12, l, l, l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* limit the inlined version to 3 moves */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return __generic_copy_to_user(to, from, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static inline unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) raw_copy_from_user(void *to, const void __user *from, unsigned long n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (__builtin_constant_p(n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return __constant_copy_from_user(to, from, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return __generic_copy_from_user(to, from, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static inline unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) raw_copy_to_user(void __user *to, const void *from, unsigned long n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (__builtin_constant_p(n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return __constant_copy_to_user(to, from, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return __generic_copy_to_user(to, from, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) #define INLINE_COPY_FROM_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) #define INLINE_COPY_TO_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) #define user_addr_max() \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) (uaccess_kernel() ? ~0UL : TASK_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) extern long strncpy_from_user(char *dst, const char __user *src, long count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) extern __must_check long strnlen_user(const char __user *str, long n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) unsigned long __clear_user(void __user *to, unsigned long n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) #define clear_user __clear_user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) #else /* !CONFIG_MMU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) #include <asm-generic/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) #endif /* _M68K_UACCESS_H */