^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2008-2009 PetaLogix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2006 Atmark Techno, Inc.
^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) #ifndef _ASM_MICROBLAZE_UACCESS_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define _ASM_MICROBLAZE_UACCESS_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/mmu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/extable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * On Microblaze the fs value is actually the top of the corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * address space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * The fs value determines whether argument validity checking should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * performed or not. If get_fs() == USER_DS, checking is performed, with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * get_fs() == KERNEL_DS, checking is bypassed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * For historical reasons, these macros are grossly misnamed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) # define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) # ifndef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) # define KERNEL_DS MAKE_MM_SEG(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) # define USER_DS KERNEL_DS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) # else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) # define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) # define USER_DS MAKE_MM_SEG(TASK_SIZE - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) # endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) # define get_fs() (current_thread_info()->addr_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) # define set_fs(val) (current_thread_info()->addr_limit = (val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) # define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #ifndef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* Check against bounds of physical memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static inline int ___range_ok(unsigned long addr, unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return ((addr < memory_start) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ((addr + size - 1) > (memory_start + memory_size - 1)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define __range_ok(addr, size) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) ___range_ok((unsigned long)(addr), (unsigned long)(size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define access_ok(addr, size) (__range_ok((addr), (size)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static inline int access_ok(const void __user *addr, unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (!size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) goto ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if ((get_fs().seg < ((unsigned long)addr)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) (get_fs().seg < ((unsigned long)addr + size - 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) pr_devel("ACCESS fail at 0x%08x (size 0x%x), seg 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) (__force u32)addr, (u32)size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) (u32)get_fs().seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) pr_devel("ACCESS OK at 0x%08x (size 0x%x), seg 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) (__force u32)addr, (u32)size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) (u32)get_fs().seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #ifdef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) # define __FIXUP_SECTION ".section .fixup,\"ax\"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) # define __EX_TABLE_SECTION ".section __ex_table,\"a\"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) # define __FIXUP_SECTION ".section .discard,\"ax\"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) # define __EX_TABLE_SECTION ".section .discard,\"ax\"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) extern unsigned long __copy_tofrom_user(void __user *to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) const void __user *from, unsigned long size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static inline unsigned long __must_check __clear_user(void __user *to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned long n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* normal memset with two words to __ex_table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) __asm__ __volatile__ ( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) "1: sb r0, %1, r0;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) " addik %0, %0, -1;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) " bneid %0, 1b;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) " addik %1, %1, 1;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) "2: " \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) __EX_TABLE_SECTION \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ".word 1b,2b;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) ".previous;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) : "=r"(n), "=r"(to) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) : "0"(n), "1"(to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static inline unsigned long __must_check clear_user(void __user *to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) unsigned long n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) might_fault();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (unlikely(!access_ok(to, n)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return __clear_user(to, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* put_user and get_user macros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) extern long __user_bad(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define __get_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) __asm__ __volatile__ ( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) "1:" insn " %1, %2, r0;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) " addk %0, r0, r0;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) "2: " \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) __FIXUP_SECTION \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) "3: brid 2b;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) " addik %0, r0, %3;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ".previous;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) __EX_TABLE_SECTION \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ".word 1b,3b;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ".previous;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) : "=&r"(__gu_err), "=r"(__gu_val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) : "r"(__gu_ptr), "i"(-EFAULT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * get_user: - Get a simple variable from user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * @x: Variable to store result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * @ptr: Source address, in user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Context: User context only. This function may sleep if pagefaults are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * This macro copies a single simple variable from user space to kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * space. It supports simple types like char and int, but not larger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * data types like structures or arrays.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * @ptr must have pointer-to-simple-variable type, and the result of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * dereferencing @ptr must be assignable to @x without a cast.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * Returns zero on success, or -EFAULT on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * On error, the variable @x is set to zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define get_user(x, ptr) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) const typeof(*(ptr)) __user *__gu_ptr = (ptr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) access_ok(__gu_ptr, sizeof(*__gu_ptr)) ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) __get_user(x, __gu_ptr) : -EFAULT; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define __get_user(x, ptr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) long __gu_err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) switch (sizeof(*(ptr))) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case 1: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) __get_user_asm("lbu", (ptr), x, __gu_err); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) case 2: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) __get_user_asm("lhu", (ptr), x, __gu_err); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case 4: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) __get_user_asm("lw", (ptr), x, __gu_err); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case 8: { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) __u64 __x = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) __gu_err = raw_copy_from_user(&__x, ptr, 8) ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) -EFAULT : 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) (x) = (typeof(x))(typeof((x) - (x)))__x; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) default: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* __gu_val = 0; __gu_err = -EINVAL;*/ __gu_err = __user_bad();\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) __gu_err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) })
^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_asm(insn, __gu_ptr, __gu_val, __gu_err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) __asm__ __volatile__ ( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) "1:" insn " %1, %2, r0;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) " addk %0, r0, r0;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) "2: " \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) __FIXUP_SECTION \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) "3: brid 2b;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) " addik %0, r0, %3;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ".previous;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) __EX_TABLE_SECTION \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ".word 1b,3b;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ".previous;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) : "=&r"(__gu_err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) : "r"(__gu_val), "r"(__gu_ptr), "i"(-EFAULT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #define __put_user_asm_8(__gu_ptr, __gu_val, __gu_err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) __asm__ __volatile__ (" lwi %0, %1, 0;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) "1: swi %0, %2, 0;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) " lwi %0, %1, 4;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) "2: swi %0, %2, 4;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) " addk %0, r0, r0;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) "3: " \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) __FIXUP_SECTION \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) "4: brid 3b;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) " addik %0, r0, %3;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ".previous;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) __EX_TABLE_SECTION \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) ".word 1b,4b,2b,4b;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) ".previous;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) : "=&r"(__gu_err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) : "r"(&__gu_val), "r"(__gu_ptr), "i"(-EFAULT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * put_user: - Write a simple value into user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * @x: Value to copy to user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * @ptr: Destination address, in user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * Context: User context only. This function may sleep if pagefaults are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * This macro copies a single simple value from kernel space to user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * space. It supports simple types like char and int, but not larger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * data types like structures or arrays.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * @ptr must have pointer-to-simple-variable type, and @x must be assignable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * to the result of dereferencing @ptr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * Returns zero on success, or -EFAULT on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) #define put_user(x, ptr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) __put_user_check((x), (ptr), sizeof(*(ptr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #define __put_user_check(x, ptr, size) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) typeof(*(ptr)) volatile __pu_val = x; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) typeof(*(ptr)) __user *__pu_addr = (ptr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) int __pu_err = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (access_ok(__pu_addr, size)) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) switch (size) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) case 1: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) __put_user_asm("sb", __pu_addr, __pu_val, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) __pu_err); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) case 2: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) __put_user_asm("sh", __pu_addr, __pu_val, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) __pu_err); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) case 4: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) __put_user_asm("sw", __pu_addr, __pu_val, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) __pu_err); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case 8: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) __put_user_asm_8(__pu_addr, __pu_val, __pu_err);\
^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) __pu_err = __user_bad(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) } else { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) __pu_err = -EFAULT; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) __pu_err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) #define __put_user(x, ptr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) __typeof__(*(ptr)) volatile __gu_val = (x); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) long __gu_err = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) switch (sizeof(__gu_val)) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) case 1: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) __put_user_asm("sb", (ptr), __gu_val, __gu_err); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) case 2: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) __put_user_asm("sh", (ptr), __gu_val, __gu_err); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case 4: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) __put_user_asm("sw", (ptr), __gu_val, __gu_err); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) case 8: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) __put_user_asm_8((ptr), __gu_val, __gu_err); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) default: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /*__gu_err = -EINVAL;*/ __gu_err = __user_bad(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) __gu_err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static inline unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) raw_copy_from_user(void *to, const void __user *from, unsigned long n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return __copy_tofrom_user((__force void __user *)to, from, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static inline unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) raw_copy_to_user(void __user *to, const void *from, unsigned long n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return __copy_tofrom_user(to, (__force const void __user *)from, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) #define INLINE_COPY_FROM_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) #define INLINE_COPY_TO_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * Copy a null terminated string from userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) extern int __strncpy_user(char *to, const char __user *from, int len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static inline long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) strncpy_from_user(char *dst, const char __user *src, long count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (!access_ok(src, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return __strncpy_user(dst, src, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * Return the size of a string (including the ending 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * Return 0 on exception, a value greater than N if too long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) extern int __strnlen_user(const char __user *sstr, int len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static inline long strnlen_user(const char __user *src, long n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (!access_ok(src, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return __strnlen_user(src, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) #endif /* _ASM_MICROBLAZE_UACCESS_H */