1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2deae26bfSKyle McMartin #ifndef __PARISC_UACCESS_H 3deae26bfSKyle McMartin #define __PARISC_UACCESS_H 4deae26bfSKyle McMartin 5deae26bfSKyle McMartin /* 6deae26bfSKyle McMartin * User space memory access functions 7deae26bfSKyle McMartin */ 8deae26bfSKyle McMartin #include <asm/page.h> 9deae26bfSKyle McMartin #include <asm/cache.h> 10deae26bfSKyle McMartin 118dd95c68SHelge Deller #include <linux/bug.h> 12aace880fSAl Viro #include <linux/string.h> 13deae26bfSKyle McMartin 14*12700c17SArnd Bergmann #define TASK_SIZE_MAX DEFAULT_TASK_SIZE 15*12700c17SArnd Bergmann #include <asm/pgtable.h> 16*12700c17SArnd Bergmann #include <asm-generic/access_ok.h> 17deae26bfSKyle McMartin 18deae26bfSKyle McMartin #define put_user __put_user 19deae26bfSKyle McMartin #define get_user __get_user 20deae26bfSKyle McMartin 21deae26bfSKyle McMartin #if !defined(CONFIG_64BIT) 2267102872SHelge Deller #define LDD_USER(sr, val, ptr) __get_user_asm64(sr, val, ptr) 2367102872SHelge Deller #define STD_USER(sr, x, ptr) __put_user_asm64(sr, x, ptr) 24deae26bfSKyle McMartin #else 2567102872SHelge Deller #define LDD_USER(sr, val, ptr) __get_user_asm(sr, val, "ldd", ptr) 2667102872SHelge Deller #define STD_USER(sr, x, ptr) __put_user_asm(sr, "std", x, ptr) 27deae26bfSKyle McMartin #endif 28deae26bfSKyle McMartin 29deae26bfSKyle McMartin /* 30cb910c17SHelge Deller * The exception table contains two values: the first is the relative offset to 31cb910c17SHelge Deller * the address of the instruction that is allowed to fault, and the second is 32cb910c17SHelge Deller * the relative offset to the address of the fixup routine. Since relative 33cb910c17SHelge Deller * addresses are used, 32bit values are sufficient even on 64bit kernel. 34deae26bfSKyle McMartin */ 35deae26bfSKyle McMartin 360de79858SHelge Deller #define ARCH_HAS_RELATIVE_EXTABLE 37deae26bfSKyle McMartin struct exception_table_entry { 380de79858SHelge Deller int insn; /* relative address of insn that is allowed to fault. */ 390de79858SHelge Deller int fixup; /* relative address of fixup routine */ 40deae26bfSKyle McMartin }; 41deae26bfSKyle McMartin 42deae26bfSKyle McMartin #define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\ 43deae26bfSKyle McMartin ".section __ex_table,\"aw\"\n" \ 440de79858SHelge Deller ".word (" #fault_addr " - .), (" #except_addr " - .)\n\t" \ 45deae26bfSKyle McMartin ".previous\n" 46deae26bfSKyle McMartin 47deae26bfSKyle McMartin /* 48d19f5e41SHelge Deller * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() creates a special exception table entry 49d19f5e41SHelge Deller * (with lowest bit set) for which the fault handler in fixup_exception() will 504b9d2a73SHelge Deller * load -EFAULT into %r29 for a read or write fault, and zeroes the target 51d19f5e41SHelge Deller * register in case of a read fault in get_user(). 52d19f5e41SHelge Deller */ 534b9d2a73SHelge Deller #define ASM_EXCEPTIONTABLE_REG 29 544b9d2a73SHelge Deller #define ASM_EXCEPTIONTABLE_VAR(__variable) \ 554b9d2a73SHelge Deller register long __variable __asm__ ("r29") = 0 56d19f5e41SHelge Deller #define ASM_EXCEPTIONTABLE_ENTRY_EFAULT( fault_addr, except_addr )\ 57d19f5e41SHelge Deller ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr + 1) 58d19f5e41SHelge Deller 5967102872SHelge Deller #define __get_user_internal(sr, val, ptr) \ 60deae26bfSKyle McMartin ({ \ 614b9d2a73SHelge Deller ASM_EXCEPTIONTABLE_VAR(__gu_err); \ 62deae26bfSKyle McMartin \ 63deae26bfSKyle McMartin switch (sizeof(*(ptr))) { \ 6467102872SHelge Deller case 1: __get_user_asm(sr, val, "ldb", ptr); break; \ 6567102872SHelge Deller case 2: __get_user_asm(sr, val, "ldh", ptr); break; \ 6667102872SHelge Deller case 4: __get_user_asm(sr, val, "ldw", ptr); break; \ 6767102872SHelge Deller case 8: LDD_USER(sr, val, ptr); break; \ 683f795cefSHelge Deller default: BUILD_BUG(); \ 69deae26bfSKyle McMartin } \ 70deae26bfSKyle McMartin \ 71deae26bfSKyle McMartin __gu_err; \ 72deae26bfSKyle McMartin }) 73deae26bfSKyle McMartin 743f795cefSHelge Deller #define __get_user(val, ptr) \ 753f795cefSHelge Deller ({ \ 7667102872SHelge Deller __get_user_internal("%%sr3,", val, ptr); \ 773f795cefSHelge Deller }) 783f795cefSHelge Deller 7967102872SHelge Deller #define __get_user_asm(sr, val, ldx, ptr) \ 803f795cefSHelge Deller { \ 813f795cefSHelge Deller register long __gu_val; \ 823f795cefSHelge Deller \ 8367102872SHelge Deller __asm__("1: " ldx " 0(" sr "%2),%0\n" \ 84d19f5e41SHelge Deller "9:\n" \ 85d19f5e41SHelge Deller ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ 86deae26bfSKyle McMartin : "=r"(__gu_val), "=r"(__gu_err) \ 873f795cefSHelge Deller : "r"(ptr), "1"(__gu_err)); \ 883f795cefSHelge Deller \ 893f795cefSHelge Deller (val) = (__force __typeof__(*(ptr))) __gu_val; \ 903f795cefSHelge Deller } 91deae26bfSKyle McMartin 9267102872SHelge Deller #define __get_kernel_nofault(dst, src, type, err_label) \ 9367102872SHelge Deller { \ 9467102872SHelge Deller type __z; \ 9567102872SHelge Deller long __err; \ 9667102872SHelge Deller __err = __get_user_internal("%%sr0,", __z, (type *)(src)); \ 9767102872SHelge Deller if (unlikely(__err)) \ 9867102872SHelge Deller goto err_label; \ 9967102872SHelge Deller else \ 10067102872SHelge Deller *(type *)(dst) = __z; \ 10167102872SHelge Deller } 10267102872SHelge Deller 10367102872SHelge Deller 104d2ad824fSHelge Deller #if !defined(CONFIG_64BIT) 105d2ad824fSHelge Deller 10667102872SHelge Deller #define __get_user_asm64(sr, val, ptr) \ 1073f795cefSHelge Deller { \ 1083f795cefSHelge Deller union { \ 1093f795cefSHelge Deller unsigned long long l; \ 1103f795cefSHelge Deller __typeof__(*(ptr)) t; \ 1113f795cefSHelge Deller } __gu_tmp; \ 1123f795cefSHelge Deller \ 113d19f5e41SHelge Deller __asm__(" copy %%r0,%R0\n" \ 11467102872SHelge Deller "1: ldw 0(" sr "%2),%0\n" \ 11567102872SHelge Deller "2: ldw 4(" sr "%2),%R0\n" \ 116d19f5e41SHelge Deller "9:\n" \ 117d19f5e41SHelge Deller ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ 118d19f5e41SHelge Deller ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \ 1193f795cefSHelge Deller : "=&r"(__gu_tmp.l), "=r"(__gu_err) \ 1203f795cefSHelge Deller : "r"(ptr), "1"(__gu_err)); \ 1213f795cefSHelge Deller \ 1223f795cefSHelge Deller (val) = __gu_tmp.t; \ 1233f795cefSHelge Deller } 124d2ad824fSHelge Deller 125d2ad824fSHelge Deller #endif /* !defined(CONFIG_64BIT) */ 126d2ad824fSHelge Deller 127d2ad824fSHelge Deller 12867102872SHelge Deller #define __put_user_internal(sr, x, ptr) \ 129deae26bfSKyle McMartin ({ \ 1304b9d2a73SHelge Deller ASM_EXCEPTIONTABLE_VAR(__pu_err); \ 131deae26bfSKyle McMartin __typeof__(*(ptr)) __x = (__typeof__(*(ptr)))(x); \ 132deae26bfSKyle McMartin \ 133deae26bfSKyle McMartin switch (sizeof(*(ptr))) { \ 13467102872SHelge Deller case 1: __put_user_asm(sr, "stb", __x, ptr); break; \ 13567102872SHelge Deller case 2: __put_user_asm(sr, "sth", __x, ptr); break; \ 13667102872SHelge Deller case 4: __put_user_asm(sr, "stw", __x, ptr); break; \ 13767102872SHelge Deller case 8: STD_USER(sr, __x, ptr); break; \ 1383f795cefSHelge Deller default: BUILD_BUG(); \ 139deae26bfSKyle McMartin } \ 140deae26bfSKyle McMartin \ 141deae26bfSKyle McMartin __pu_err; \ 142deae26bfSKyle McMartin }) 143deae26bfSKyle McMartin 1443f795cefSHelge Deller #define __put_user(x, ptr) \ 1453f795cefSHelge Deller ({ \ 14667102872SHelge Deller __put_user_internal("%%sr3,", x, ptr); \ 1473f795cefSHelge Deller }) 1483f795cefSHelge Deller 14967102872SHelge Deller #define __put_kernel_nofault(dst, src, type, err_label) \ 15067102872SHelge Deller { \ 15167102872SHelge Deller type __z = *(type *)(src); \ 15267102872SHelge Deller long __err; \ 15367102872SHelge Deller __err = __put_user_internal("%%sr0,", __z, (type *)(dst)); \ 15467102872SHelge Deller if (unlikely(__err)) \ 15567102872SHelge Deller goto err_label; \ 15667102872SHelge Deller } 15767102872SHelge Deller 15867102872SHelge Deller 15967102872SHelge Deller 1603f795cefSHelge Deller 161deae26bfSKyle McMartin /* 162deae26bfSKyle McMartin * The "__put_user/kernel_asm()" macros tell gcc they read from memory 163deae26bfSKyle McMartin * instead of writing. This is because they do not write to any memory 164deae26bfSKyle McMartin * gcc knows about, so there are no aliasing issues. These macros must 165d19f5e41SHelge Deller * also be aware that fixups are executed in the context of the fault, 166d19f5e41SHelge Deller * and any registers used there must be listed as clobbers. 1674b9d2a73SHelge Deller * The register holding the possible EFAULT error (ASM_EXCEPTIONTABLE_REG) 1684b9d2a73SHelge Deller * is already listed as input and output register. 169deae26bfSKyle McMartin */ 170deae26bfSKyle McMartin 17167102872SHelge Deller #define __put_user_asm(sr, stx, x, ptr) \ 172deae26bfSKyle McMartin __asm__ __volatile__ ( \ 17367102872SHelge Deller "1: " stx " %2,0(" sr "%1)\n" \ 174d19f5e41SHelge Deller "9:\n" \ 175d19f5e41SHelge Deller ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ 176deae26bfSKyle McMartin : "=r"(__pu_err) \ 177d19f5e41SHelge Deller : "r"(ptr), "r"(x), "0"(__pu_err)) 178deae26bfSKyle McMartin 179deae26bfSKyle McMartin 180deae26bfSKyle McMartin #if !defined(CONFIG_64BIT) 181deae26bfSKyle McMartin 18267102872SHelge Deller #define __put_user_asm64(sr, __val, ptr) do { \ 183deae26bfSKyle McMartin __asm__ __volatile__ ( \ 18467102872SHelge Deller "1: stw %2,0(" sr "%1)\n" \ 18567102872SHelge Deller "2: stw %R2,4(" sr "%1)\n" \ 186d19f5e41SHelge Deller "9:\n" \ 187d19f5e41SHelge Deller ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ 188d19f5e41SHelge Deller ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \ 189deae26bfSKyle McMartin : "=r"(__pu_err) \ 190d19f5e41SHelge Deller : "r"(ptr), "r"(__val), "0"(__pu_err)); \ 191deae26bfSKyle McMartin } while (0) 192deae26bfSKyle McMartin 193deae26bfSKyle McMartin #endif /* !defined(CONFIG_64BIT) */ 194deae26bfSKyle McMartin 195deae26bfSKyle McMartin 196deae26bfSKyle McMartin /* 197deae26bfSKyle McMartin * Complex access routines -- external declarations 198deae26bfSKyle McMartin */ 199deae26bfSKyle McMartin 200b1195c0eSJames Bottomley extern long strncpy_from_user(char *, const char __user *, long); 20167102872SHelge Deller extern __must_check unsigned lclear_user(void __user *, unsigned long); 2021260dea6SHelge Deller extern __must_check long strnlen_user(const char __user *src, long n); 203deae26bfSKyle McMartin /* 204deae26bfSKyle McMartin * Complex access routines -- macros 205deae26bfSKyle McMartin */ 206deae26bfSKyle McMartin 207deae26bfSKyle McMartin #define clear_user lclear_user 208deae26bfSKyle McMartin #define __clear_user lclear_user 209deae26bfSKyle McMartin 210f64fd180SAl Viro unsigned long __must_check raw_copy_to_user(void __user *dst, const void *src, 2119e91db6bSHelge Deller unsigned long len); 212f64fd180SAl Viro unsigned long __must_check raw_copy_from_user(void *dst, const void __user *src, 2139e91db6bSHelge Deller unsigned long len); 214f64fd180SAl Viro #define INLINE_COPY_TO_USER 215f64fd180SAl Viro #define INLINE_COPY_FROM_USER 2169e91db6bSHelge Deller 217e448372cSHelge Deller struct pt_regs; 218c61c25ebSKyle McMartin int fixup_exception(struct pt_regs *regs); 219c61c25ebSKyle McMartin 220deae26bfSKyle McMartin #endif /* __PARISC_UACCESS_H */ 221