18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __ALPHA_UACCESS_H 38c2ecf20Sopenharmony_ci#define __ALPHA_UACCESS_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci/* 68c2ecf20Sopenharmony_ci * The fs value determines whether argument validity checking should be 78c2ecf20Sopenharmony_ci * performed or not. If get_fs() == USER_DS, checking is performed, with 88c2ecf20Sopenharmony_ci * get_fs() == KERNEL_DS, checking is bypassed. 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Or at least it did once upon a time. Nowadays it is a mask that 118c2ecf20Sopenharmony_ci * defines which bits of the address space are off limits. This is a 128c2ecf20Sopenharmony_ci * wee bit faster than the above. 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * For historical reasons, these macros are grossly misnamed. 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#define KERNEL_DS ((mm_segment_t) { 0UL }) 188c2ecf20Sopenharmony_ci#define USER_DS ((mm_segment_t) { -0x40000000000UL }) 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define get_fs() (current_thread_info()->addr_limit) 218c2ecf20Sopenharmony_ci#define set_fs(x) (current_thread_info()->addr_limit = (x)) 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg) 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci/* 268c2ecf20Sopenharmony_ci * Is a address valid? This does a straightforward calculation rather 278c2ecf20Sopenharmony_ci * than tests. 288c2ecf20Sopenharmony_ci * 298c2ecf20Sopenharmony_ci * Address valid if: 308c2ecf20Sopenharmony_ci * - "addr" doesn't have any high-bits set 318c2ecf20Sopenharmony_ci * - AND "size" doesn't have any high-bits set 328c2ecf20Sopenharmony_ci * - AND "addr+size-(size != 0)" doesn't have any high-bits set 338c2ecf20Sopenharmony_ci * - OR we are in kernel mode. 348c2ecf20Sopenharmony_ci */ 358c2ecf20Sopenharmony_ci#define __access_ok(addr, size) ({ \ 368c2ecf20Sopenharmony_ci unsigned long __ao_a = (addr), __ao_b = (size); \ 378c2ecf20Sopenharmony_ci unsigned long __ao_end = __ao_a + __ao_b - !!__ao_b; \ 388c2ecf20Sopenharmony_ci (get_fs().seg & (__ao_a | __ao_b | __ao_end)) == 0; }) 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#define access_ok(addr, size) \ 418c2ecf20Sopenharmony_ci({ \ 428c2ecf20Sopenharmony_ci __chk_user_ptr(addr); \ 438c2ecf20Sopenharmony_ci __access_ok(((unsigned long)(addr)), (size)); \ 448c2ecf20Sopenharmony_ci}) 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci/* 478c2ecf20Sopenharmony_ci * These are the main single-value transfer routines. They automatically 488c2ecf20Sopenharmony_ci * use the right size if we just have the right pointer type. 498c2ecf20Sopenharmony_ci * 508c2ecf20Sopenharmony_ci * As the alpha uses the same address space for kernel and user 518c2ecf20Sopenharmony_ci * data, we can just do these as direct assignments. (Of course, the 528c2ecf20Sopenharmony_ci * exception handling means that it's no longer "just"...) 538c2ecf20Sopenharmony_ci * 548c2ecf20Sopenharmony_ci * Careful to not 558c2ecf20Sopenharmony_ci * (a) re-use the arguments for side effects (sizeof/typeof is ok) 568c2ecf20Sopenharmony_ci * (b) require any knowledge of processes at this stage 578c2ecf20Sopenharmony_ci */ 588c2ecf20Sopenharmony_ci#define put_user(x, ptr) \ 598c2ecf20Sopenharmony_ci __put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) 608c2ecf20Sopenharmony_ci#define get_user(x, ptr) \ 618c2ecf20Sopenharmony_ci __get_user_check((x), (ptr), sizeof(*(ptr))) 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci/* 648c2ecf20Sopenharmony_ci * The "__xxx" versions do not do address space checking, useful when 658c2ecf20Sopenharmony_ci * doing multiple accesses to the same area (the programmer has to do the 668c2ecf20Sopenharmony_ci * checks by hand with "access_ok()") 678c2ecf20Sopenharmony_ci */ 688c2ecf20Sopenharmony_ci#define __put_user(x, ptr) \ 698c2ecf20Sopenharmony_ci __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) 708c2ecf20Sopenharmony_ci#define __get_user(x, ptr) \ 718c2ecf20Sopenharmony_ci __get_user_nocheck((x), (ptr), sizeof(*(ptr))) 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci/* 748c2ecf20Sopenharmony_ci * The "lda %1, 2b-1b(%0)" bits are magic to get the assembler to 758c2ecf20Sopenharmony_ci * encode the bits we need for resolving the exception. See the 768c2ecf20Sopenharmony_ci * more extensive comments with fixup_inline_exception below for 778c2ecf20Sopenharmony_ci * more information. 788c2ecf20Sopenharmony_ci */ 798c2ecf20Sopenharmony_ci#define EXC(label,cont,res,err) \ 808c2ecf20Sopenharmony_ci ".section __ex_table,\"a\"\n" \ 818c2ecf20Sopenharmony_ci " .long "#label"-.\n" \ 828c2ecf20Sopenharmony_ci " lda "#res","#cont"-"#label"("#err")\n" \ 838c2ecf20Sopenharmony_ci ".previous\n" 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ciextern void __get_user_unknown(void); 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci#define __get_user_nocheck(x, ptr, size) \ 888c2ecf20Sopenharmony_ci({ \ 898c2ecf20Sopenharmony_ci long __gu_err = 0; \ 908c2ecf20Sopenharmony_ci unsigned long __gu_val; \ 918c2ecf20Sopenharmony_ci __chk_user_ptr(ptr); \ 928c2ecf20Sopenharmony_ci switch (size) { \ 938c2ecf20Sopenharmony_ci case 1: __get_user_8(ptr); break; \ 948c2ecf20Sopenharmony_ci case 2: __get_user_16(ptr); break; \ 958c2ecf20Sopenharmony_ci case 4: __get_user_32(ptr); break; \ 968c2ecf20Sopenharmony_ci case 8: __get_user_64(ptr); break; \ 978c2ecf20Sopenharmony_ci default: __get_user_unknown(); break; \ 988c2ecf20Sopenharmony_ci } \ 998c2ecf20Sopenharmony_ci (x) = (__force __typeof__(*(ptr))) __gu_val; \ 1008c2ecf20Sopenharmony_ci __gu_err; \ 1018c2ecf20Sopenharmony_ci}) 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci#define __get_user_check(x, ptr, size) \ 1048c2ecf20Sopenharmony_ci({ \ 1058c2ecf20Sopenharmony_ci long __gu_err = -EFAULT; \ 1068c2ecf20Sopenharmony_ci unsigned long __gu_val = 0; \ 1078c2ecf20Sopenharmony_ci const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ 1088c2ecf20Sopenharmony_ci if (__access_ok((unsigned long)__gu_addr, size)) { \ 1098c2ecf20Sopenharmony_ci __gu_err = 0; \ 1108c2ecf20Sopenharmony_ci switch (size) { \ 1118c2ecf20Sopenharmony_ci case 1: __get_user_8(__gu_addr); break; \ 1128c2ecf20Sopenharmony_ci case 2: __get_user_16(__gu_addr); break; \ 1138c2ecf20Sopenharmony_ci case 4: __get_user_32(__gu_addr); break; \ 1148c2ecf20Sopenharmony_ci case 8: __get_user_64(__gu_addr); break; \ 1158c2ecf20Sopenharmony_ci default: __get_user_unknown(); break; \ 1168c2ecf20Sopenharmony_ci } \ 1178c2ecf20Sopenharmony_ci } \ 1188c2ecf20Sopenharmony_ci (x) = (__force __typeof__(*(ptr))) __gu_val; \ 1198c2ecf20Sopenharmony_ci __gu_err; \ 1208c2ecf20Sopenharmony_ci}) 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistruct __large_struct { unsigned long buf[100]; }; 1238c2ecf20Sopenharmony_ci#define __m(x) (*(struct __large_struct __user *)(x)) 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci#define __get_user_64(addr) \ 1268c2ecf20Sopenharmony_ci __asm__("1: ldq %0,%2\n" \ 1278c2ecf20Sopenharmony_ci "2:\n" \ 1288c2ecf20Sopenharmony_ci EXC(1b,2b,%0,%1) \ 1298c2ecf20Sopenharmony_ci : "=r"(__gu_val), "=r"(__gu_err) \ 1308c2ecf20Sopenharmony_ci : "m"(__m(addr)), "1"(__gu_err)) 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci#define __get_user_32(addr) \ 1338c2ecf20Sopenharmony_ci __asm__("1: ldl %0,%2\n" \ 1348c2ecf20Sopenharmony_ci "2:\n" \ 1358c2ecf20Sopenharmony_ci EXC(1b,2b,%0,%1) \ 1368c2ecf20Sopenharmony_ci : "=r"(__gu_val), "=r"(__gu_err) \ 1378c2ecf20Sopenharmony_ci : "m"(__m(addr)), "1"(__gu_err)) 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci#ifdef __alpha_bwx__ 1408c2ecf20Sopenharmony_ci/* Those lucky bastards with ev56 and later CPUs can do byte/word moves. */ 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci#define __get_user_16(addr) \ 1438c2ecf20Sopenharmony_ci __asm__("1: ldwu %0,%2\n" \ 1448c2ecf20Sopenharmony_ci "2:\n" \ 1458c2ecf20Sopenharmony_ci EXC(1b,2b,%0,%1) \ 1468c2ecf20Sopenharmony_ci : "=r"(__gu_val), "=r"(__gu_err) \ 1478c2ecf20Sopenharmony_ci : "m"(__m(addr)), "1"(__gu_err)) 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci#define __get_user_8(addr) \ 1508c2ecf20Sopenharmony_ci __asm__("1: ldbu %0,%2\n" \ 1518c2ecf20Sopenharmony_ci "2:\n" \ 1528c2ecf20Sopenharmony_ci EXC(1b,2b,%0,%1) \ 1538c2ecf20Sopenharmony_ci : "=r"(__gu_val), "=r"(__gu_err) \ 1548c2ecf20Sopenharmony_ci : "m"(__m(addr)), "1"(__gu_err)) 1558c2ecf20Sopenharmony_ci#else 1568c2ecf20Sopenharmony_ci/* Unfortunately, we can't get an unaligned access trap for the sub-word 1578c2ecf20Sopenharmony_ci load, so we have to do a general unaligned operation. */ 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci#define __get_user_16(addr) \ 1608c2ecf20Sopenharmony_ci{ \ 1618c2ecf20Sopenharmony_ci long __gu_tmp; \ 1628c2ecf20Sopenharmony_ci __asm__("1: ldq_u %0,0(%3)\n" \ 1638c2ecf20Sopenharmony_ci "2: ldq_u %1,1(%3)\n" \ 1648c2ecf20Sopenharmony_ci " extwl %0,%3,%0\n" \ 1658c2ecf20Sopenharmony_ci " extwh %1,%3,%1\n" \ 1668c2ecf20Sopenharmony_ci " or %0,%1,%0\n" \ 1678c2ecf20Sopenharmony_ci "3:\n" \ 1688c2ecf20Sopenharmony_ci EXC(1b,3b,%0,%2) \ 1698c2ecf20Sopenharmony_ci EXC(2b,3b,%0,%2) \ 1708c2ecf20Sopenharmony_ci : "=&r"(__gu_val), "=&r"(__gu_tmp), "=r"(__gu_err) \ 1718c2ecf20Sopenharmony_ci : "r"(addr), "2"(__gu_err)); \ 1728c2ecf20Sopenharmony_ci} 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci#define __get_user_8(addr) \ 1758c2ecf20Sopenharmony_ci __asm__("1: ldq_u %0,0(%2)\n" \ 1768c2ecf20Sopenharmony_ci " extbl %0,%2,%0\n" \ 1778c2ecf20Sopenharmony_ci "2:\n" \ 1788c2ecf20Sopenharmony_ci EXC(1b,2b,%0,%1) \ 1798c2ecf20Sopenharmony_ci : "=&r"(__gu_val), "=r"(__gu_err) \ 1808c2ecf20Sopenharmony_ci : "r"(addr), "1"(__gu_err)) 1818c2ecf20Sopenharmony_ci#endif 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ciextern void __put_user_unknown(void); 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci#define __put_user_nocheck(x, ptr, size) \ 1868c2ecf20Sopenharmony_ci({ \ 1878c2ecf20Sopenharmony_ci long __pu_err = 0; \ 1888c2ecf20Sopenharmony_ci __chk_user_ptr(ptr); \ 1898c2ecf20Sopenharmony_ci switch (size) { \ 1908c2ecf20Sopenharmony_ci case 1: __put_user_8(x, ptr); break; \ 1918c2ecf20Sopenharmony_ci case 2: __put_user_16(x, ptr); break; \ 1928c2ecf20Sopenharmony_ci case 4: __put_user_32(x, ptr); break; \ 1938c2ecf20Sopenharmony_ci case 8: __put_user_64(x, ptr); break; \ 1948c2ecf20Sopenharmony_ci default: __put_user_unknown(); break; \ 1958c2ecf20Sopenharmony_ci } \ 1968c2ecf20Sopenharmony_ci __pu_err; \ 1978c2ecf20Sopenharmony_ci}) 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci#define __put_user_check(x, ptr, size) \ 2008c2ecf20Sopenharmony_ci({ \ 2018c2ecf20Sopenharmony_ci long __pu_err = -EFAULT; \ 2028c2ecf20Sopenharmony_ci __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ 2038c2ecf20Sopenharmony_ci if (__access_ok((unsigned long)__pu_addr, size)) { \ 2048c2ecf20Sopenharmony_ci __pu_err = 0; \ 2058c2ecf20Sopenharmony_ci switch (size) { \ 2068c2ecf20Sopenharmony_ci case 1: __put_user_8(x, __pu_addr); break; \ 2078c2ecf20Sopenharmony_ci case 2: __put_user_16(x, __pu_addr); break; \ 2088c2ecf20Sopenharmony_ci case 4: __put_user_32(x, __pu_addr); break; \ 2098c2ecf20Sopenharmony_ci case 8: __put_user_64(x, __pu_addr); break; \ 2108c2ecf20Sopenharmony_ci default: __put_user_unknown(); break; \ 2118c2ecf20Sopenharmony_ci } \ 2128c2ecf20Sopenharmony_ci } \ 2138c2ecf20Sopenharmony_ci __pu_err; \ 2148c2ecf20Sopenharmony_ci}) 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci/* 2178c2ecf20Sopenharmony_ci * The "__put_user_xx()" macros tell gcc they read from memory 2188c2ecf20Sopenharmony_ci * instead of writing: this is because they do not write to 2198c2ecf20Sopenharmony_ci * any memory gcc knows about, so there are no aliasing issues 2208c2ecf20Sopenharmony_ci */ 2218c2ecf20Sopenharmony_ci#define __put_user_64(x, addr) \ 2228c2ecf20Sopenharmony_ci__asm__ __volatile__("1: stq %r2,%1\n" \ 2238c2ecf20Sopenharmony_ci "2:\n" \ 2248c2ecf20Sopenharmony_ci EXC(1b,2b,$31,%0) \ 2258c2ecf20Sopenharmony_ci : "=r"(__pu_err) \ 2268c2ecf20Sopenharmony_ci : "m" (__m(addr)), "rJ" (x), "0"(__pu_err)) 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci#define __put_user_32(x, addr) \ 2298c2ecf20Sopenharmony_ci__asm__ __volatile__("1: stl %r2,%1\n" \ 2308c2ecf20Sopenharmony_ci "2:\n" \ 2318c2ecf20Sopenharmony_ci EXC(1b,2b,$31,%0) \ 2328c2ecf20Sopenharmony_ci : "=r"(__pu_err) \ 2338c2ecf20Sopenharmony_ci : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci#ifdef __alpha_bwx__ 2368c2ecf20Sopenharmony_ci/* Those lucky bastards with ev56 and later CPUs can do byte/word moves. */ 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci#define __put_user_16(x, addr) \ 2398c2ecf20Sopenharmony_ci__asm__ __volatile__("1: stw %r2,%1\n" \ 2408c2ecf20Sopenharmony_ci "2:\n" \ 2418c2ecf20Sopenharmony_ci EXC(1b,2b,$31,%0) \ 2428c2ecf20Sopenharmony_ci : "=r"(__pu_err) \ 2438c2ecf20Sopenharmony_ci : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci#define __put_user_8(x, addr) \ 2468c2ecf20Sopenharmony_ci__asm__ __volatile__("1: stb %r2,%1\n" \ 2478c2ecf20Sopenharmony_ci "2:\n" \ 2488c2ecf20Sopenharmony_ci EXC(1b,2b,$31,%0) \ 2498c2ecf20Sopenharmony_ci : "=r"(__pu_err) \ 2508c2ecf20Sopenharmony_ci : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) 2518c2ecf20Sopenharmony_ci#else 2528c2ecf20Sopenharmony_ci/* Unfortunately, we can't get an unaligned access trap for the sub-word 2538c2ecf20Sopenharmony_ci write, so we have to do a general unaligned operation. */ 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci#define __put_user_16(x, addr) \ 2568c2ecf20Sopenharmony_ci{ \ 2578c2ecf20Sopenharmony_ci long __pu_tmp1, __pu_tmp2, __pu_tmp3, __pu_tmp4; \ 2588c2ecf20Sopenharmony_ci __asm__ __volatile__( \ 2598c2ecf20Sopenharmony_ci "1: ldq_u %2,1(%5)\n" \ 2608c2ecf20Sopenharmony_ci "2: ldq_u %1,0(%5)\n" \ 2618c2ecf20Sopenharmony_ci " inswh %6,%5,%4\n" \ 2628c2ecf20Sopenharmony_ci " inswl %6,%5,%3\n" \ 2638c2ecf20Sopenharmony_ci " mskwh %2,%5,%2\n" \ 2648c2ecf20Sopenharmony_ci " mskwl %1,%5,%1\n" \ 2658c2ecf20Sopenharmony_ci " or %2,%4,%2\n" \ 2668c2ecf20Sopenharmony_ci " or %1,%3,%1\n" \ 2678c2ecf20Sopenharmony_ci "3: stq_u %2,1(%5)\n" \ 2688c2ecf20Sopenharmony_ci "4: stq_u %1,0(%5)\n" \ 2698c2ecf20Sopenharmony_ci "5:\n" \ 2708c2ecf20Sopenharmony_ci EXC(1b,5b,$31,%0) \ 2718c2ecf20Sopenharmony_ci EXC(2b,5b,$31,%0) \ 2728c2ecf20Sopenharmony_ci EXC(3b,5b,$31,%0) \ 2738c2ecf20Sopenharmony_ci EXC(4b,5b,$31,%0) \ 2748c2ecf20Sopenharmony_ci : "=r"(__pu_err), "=&r"(__pu_tmp1), \ 2758c2ecf20Sopenharmony_ci "=&r"(__pu_tmp2), "=&r"(__pu_tmp3), \ 2768c2ecf20Sopenharmony_ci "=&r"(__pu_tmp4) \ 2778c2ecf20Sopenharmony_ci : "r"(addr), "r"((unsigned long)(x)), "0"(__pu_err)); \ 2788c2ecf20Sopenharmony_ci} 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci#define __put_user_8(x, addr) \ 2818c2ecf20Sopenharmony_ci{ \ 2828c2ecf20Sopenharmony_ci long __pu_tmp1, __pu_tmp2; \ 2838c2ecf20Sopenharmony_ci __asm__ __volatile__( \ 2848c2ecf20Sopenharmony_ci "1: ldq_u %1,0(%4)\n" \ 2858c2ecf20Sopenharmony_ci " insbl %3,%4,%2\n" \ 2868c2ecf20Sopenharmony_ci " mskbl %1,%4,%1\n" \ 2878c2ecf20Sopenharmony_ci " or %1,%2,%1\n" \ 2888c2ecf20Sopenharmony_ci "2: stq_u %1,0(%4)\n" \ 2898c2ecf20Sopenharmony_ci "3:\n" \ 2908c2ecf20Sopenharmony_ci EXC(1b,3b,$31,%0) \ 2918c2ecf20Sopenharmony_ci EXC(2b,3b,$31,%0) \ 2928c2ecf20Sopenharmony_ci : "=r"(__pu_err), \ 2938c2ecf20Sopenharmony_ci "=&r"(__pu_tmp1), "=&r"(__pu_tmp2) \ 2948c2ecf20Sopenharmony_ci : "r"((unsigned long)(x)), "r"(addr), "0"(__pu_err)); \ 2958c2ecf20Sopenharmony_ci} 2968c2ecf20Sopenharmony_ci#endif 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci/* 3008c2ecf20Sopenharmony_ci * Complex access routines 3018c2ecf20Sopenharmony_ci */ 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ciextern long __copy_user(void *to, const void *from, long len); 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_cistatic inline unsigned long 3068c2ecf20Sopenharmony_ciraw_copy_from_user(void *to, const void __user *from, unsigned long len) 3078c2ecf20Sopenharmony_ci{ 3088c2ecf20Sopenharmony_ci return __copy_user(to, (__force const void *)from, len); 3098c2ecf20Sopenharmony_ci} 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_cistatic inline unsigned long 3128c2ecf20Sopenharmony_ciraw_copy_to_user(void __user *to, const void *from, unsigned long len) 3138c2ecf20Sopenharmony_ci{ 3148c2ecf20Sopenharmony_ci return __copy_user((__force void *)to, from, len); 3158c2ecf20Sopenharmony_ci} 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ciextern long __clear_user(void __user *to, long len); 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ciextern inline long 3208c2ecf20Sopenharmony_ciclear_user(void __user *to, long len) 3218c2ecf20Sopenharmony_ci{ 3228c2ecf20Sopenharmony_ci if (__access_ok((unsigned long)to, len)) 3238c2ecf20Sopenharmony_ci len = __clear_user(to, len); 3248c2ecf20Sopenharmony_ci return len; 3258c2ecf20Sopenharmony_ci} 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci#define user_addr_max() \ 3288c2ecf20Sopenharmony_ci (uaccess_kernel() ? ~0UL : TASK_SIZE) 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ciextern long strncpy_from_user(char *dest, const char __user *src, long count); 3318c2ecf20Sopenharmony_ciextern __must_check long strnlen_user(const char __user *str, long n); 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci#include <asm/extable.h> 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci#endif /* __ALPHA_UACCESS_H */ 336