^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) // Copyright (C) 2005-2017 Andes Technology Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #ifndef _ASMANDES_UACCESS_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #define _ASMANDES_UACCESS_H
^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/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/memory.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * The exception table consists of pairs of addresses: the first is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * address of an instruction that is allowed to fault, and the second is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * the address at which the program should continue. No registers are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * modified, so it is entirely up to the continuation code to figure out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * what to do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * All the routines below use bits of fixup code that are out of line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * with the main instruction path. This means when everything is well,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * we don't even have to jump over them. Further, they do not intrude
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * on our cache or tlb entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct exception_table_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) unsigned long insn, fixup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) extern int fixup_exception(struct pt_regs *regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define KERNEL_DS ((mm_segment_t) { ~0UL })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define USER_DS ((mm_segment_t) {TASK_SIZE - 1})
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define get_fs() (current_thread_info()->addr_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define user_addr_max get_fs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static inline void set_fs(mm_segment_t fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) current_thread_info()->addr_limit = fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define uaccess_kernel() (get_fs() == KERNEL_DS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define __range_ok(addr, size) (size <= get_fs() && addr <= (get_fs() -size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define access_ok(addr, size) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) __range_ok((unsigned long)addr, (unsigned long)size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Single-value transfer routines. They automatically use the right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * size if we just have the right pointer type. Note that the functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * which read from user space (*get_*) need to take care not to leak
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * kernel data even if the calling code is buggy and fails to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * the return value. This means zeroing out the destination variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * or buffer on error. Normally this is done out of line by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * fixup code, but there are a few places where it intrudes on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * main code path. When we only write to user space, there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * problem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * The "__xxx" versions of the user access functions do not verify the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * address space - it must have been done previously with a separate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * "access_ok()" call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * The "xxx_error" versions set the third argument to EFAULT if an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * error occurs, and leave it unchanged on success. Note that these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * versions are void (ie, don't return a value as such).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define get_user(x, ptr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) long __gu_err = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) __get_user_check((x), (ptr), __gu_err); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) __gu_err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define __get_user_error(x, ptr, err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) __get_user_check((x), (ptr), (err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) (void)0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define __get_user(x, ptr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) long __gu_err = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) const __typeof__(*(ptr)) __user *__p = (ptr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) __get_user_err((x), __p, (__gu_err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) __gu_err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define __get_user_check(x, ptr, err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) const __typeof__(*(ptr)) __user *__p = (ptr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) might_fault(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (access_ok(__p, sizeof(*__p))) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) __get_user_err((x), __p, (err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) } else { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) (x) = 0; (err) = -EFAULT; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define __get_user_err(x, ptr, err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) unsigned long __gu_val; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) __chk_user_ptr(ptr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) switch (sizeof(*(ptr))) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) case 1: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) __get_user_asm("lbi", __gu_val, (ptr), (err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) case 2: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) __get_user_asm("lhi", __gu_val, (ptr), (err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) case 4: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) __get_user_asm("lwi", __gu_val, (ptr), (err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) case 8: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) __get_user_asm_dword(__gu_val, (ptr), (err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) default: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) BUILD_BUG(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) (x) = (__force __typeof__(*(ptr)))__gu_val; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define __get_user_asm(inst, x, addr, err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) __asm__ __volatile__ ( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) "1: "inst" %1,[%2]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) "2:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) " .section .fixup,\"ax\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) " .align 2\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) "3: move %0, %3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) " move %1, #0\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) " b 2b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) " .previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) " .section __ex_table,\"a\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) " .align 3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) " .long 1b, 3b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) " .previous" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) : "+r" (err), "=&r" (x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) : "r" (addr), "i" (-EFAULT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) : "cc")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #ifdef __NDS32_EB__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define __gu_reg_oper0 "%H1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define __gu_reg_oper1 "%L1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define __gu_reg_oper0 "%L1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define __gu_reg_oper1 "%H1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define __get_user_asm_dword(x, addr, err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) __asm__ __volatile__ ( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) "\n1:\tlwi " __gu_reg_oper0 ",[%2]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) "\n2:\tlwi " __gu_reg_oper1 ",[%2+4]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) "3:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) " .section .fixup,\"ax\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) " .align 2\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) "4: move %0, %3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) " b 3b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) " .previous\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 3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) " .long 1b, 4b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) " .long 2b, 4b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) " .previous" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) : "+r"(err), "=&r"(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) : "r"(addr), "i"(-EFAULT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) : "cc")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define put_user(x, ptr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) long __pu_err = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) __put_user_check((x), (ptr), __pu_err); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) __pu_err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define __put_user(x, ptr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) long __pu_err = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) __typeof__(*(ptr)) __user *__p = (ptr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) __put_user_err((x), __p, __pu_err); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) __pu_err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define __put_user_error(x, ptr, err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) __put_user_err((x), (ptr), (err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) (void)0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define __put_user_check(x, ptr, err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) __typeof__(*(ptr)) __user *__p = (ptr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) might_fault(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (access_ok(__p, sizeof(*__p))) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) __put_user_err((x), __p, (err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) } else { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) (err) = -EFAULT; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define __put_user_err(x, ptr, err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) __typeof__(*(ptr)) __pu_val = (x); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) __chk_user_ptr(ptr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) switch (sizeof(*(ptr))) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) case 1: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) __put_user_asm("sbi", __pu_val, (ptr), (err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case 2: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) __put_user_asm("shi", __pu_val, (ptr), (err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case 4: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) __put_user_asm("swi", __pu_val, (ptr), (err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case 8: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) __put_user_asm_dword(__pu_val, (ptr), (err)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) default: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) BUILD_BUG(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #define __put_user_asm(inst, x, addr, err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) __asm__ __volatile__ ( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) "1: "inst" %1,[%2]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) "2:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) " .section .fixup,\"ax\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) " .align 2\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) "3: move %0, %3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) " b 2b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) " .previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) " .section __ex_table,\"a\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) " .align 3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) " .long 1b, 3b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) " .previous" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) : "+r" (err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) : "r" (x), "r" (addr), "i" (-EFAULT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) : "cc")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #ifdef __NDS32_EB__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define __pu_reg_oper0 "%H2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #define __pu_reg_oper1 "%L2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) #define __pu_reg_oper0 "%L2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #define __pu_reg_oper1 "%H2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #define __put_user_asm_dword(x, addr, err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) __asm__ __volatile__ ( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) "\n1:\tswi " __pu_reg_oper0 ",[%1]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) "\n2:\tswi " __pu_reg_oper1 ",[%1+4]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) "3:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) " .section .fixup,\"ax\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) " .align 2\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) "4: move %0, %3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) " b 3b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) " .previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) " .section __ex_table,\"a\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) " .align 3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) " .long 1b, 4b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) " .long 2b, 4b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) " .previous" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) : "+r"(err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) : "r"(addr), "r"(x), "i"(-EFAULT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) : "cc")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) extern unsigned long __arch_clear_user(void __user * addr, unsigned long n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) extern long strncpy_from_user(char *dest, const char __user * src, long count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) extern __must_check long strlen_user(const char __user * str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) extern __must_check long strnlen_user(const char __user * str, long n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) extern unsigned long __arch_copy_from_user(void *to, const void __user * from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) unsigned long n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) extern unsigned long __arch_copy_to_user(void __user * to, const void *from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) unsigned long n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) #define raw_copy_from_user __arch_copy_from_user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #define raw_copy_to_user __arch_copy_to_user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #define INLINE_COPY_FROM_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) #define INLINE_COPY_TO_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static inline unsigned long clear_user(void __user * to, unsigned long n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (access_ok(to, n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) n = __arch_clear_user(to, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static inline unsigned long __clear_user(void __user * to, unsigned long n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return __arch_clear_user(to, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) #endif /* _ASMNDS32_UACCESS_H */