uaccess.h revision c6dc9f0a4eeb7c014904475372c66e6d0ac5a572
1b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* MN10300 userspace access functions 2b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * 3b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * Written by David Howells (dhowells@redhat.com) 5b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * 6b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * This program is free software; you can redistribute it and/or 7b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * modify it under the terms of the GNU General Public Licence 8b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * as published by the Free Software Foundation; either version 9b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * 2 of the Licence, or (at your option) any later version. 10b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */ 11b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#ifndef _ASM_UACCESS_H 12b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define _ASM_UACCESS_H 13b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 14b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* 15b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * User space memory access functions 16b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */ 177c7fcf762e405eb040ee10d22d656a791f616122David Howells#include <linux/thread_info.h> 1835052cffe0081904f3362c05818db900dd9dc7deDavid Howells#include <linux/kernel.h> 19b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#include <asm/page.h> 20b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#include <asm/errno.h> 21b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 22b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define VERIFY_READ 0 23b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define VERIFY_WRITE 1 24b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 25b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* 26b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * The fs value determines whether argument validity checking should be 27b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * performed or not. If get_fs() == USER_DS, checking is performed, with 28b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * get_fs() == KERNEL_DS, checking is bypassed. 29b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * 30b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * For historical reasons, these macros are grossly misnamed. 31b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */ 32b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) 33b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 34b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define KERNEL_XDS MAKE_MM_SEG(0xBFFFFFFF) 35b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define KERNEL_DS MAKE_MM_SEG(0x9FFFFFFF) 36b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define USER_DS MAKE_MM_SEG(TASK_SIZE) 37b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 38b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define get_ds() (KERNEL_DS) 39b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define get_fs() (current_thread_info()->addr_limit) 40b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define set_fs(x) (current_thread_info()->addr_limit = (x)) 41b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __kernel_ds_p() (current_thread_info()->addr_limit.seg == 0x9FFFFFFF) 42b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 43b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define segment_eq(a, b) ((a).seg == (b).seg) 44b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 45b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __addr_ok(addr) \ 46b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ((unsigned long)(addr) < (current_thread_info()->addr_limit.seg)) 47b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 48b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* 49b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * check that a range of addresses falls within the current address limit 50b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */ 51b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline int ___range_ok(unsigned long addr, unsigned int size) 52b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{ 53b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells int flag = 1, tmp; 54b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 55b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells asm(" add %3,%1 \n" /* set C-flag if addr + size > 4Gb */ 56b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " bcs 0f \n" 57b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " cmp %4,%1 \n" /* jump if addr+size>limit (error) */ 58b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " bhi 0f \n" 59b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " clr %0 \n" /* mark okay */ 60b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "0: \n" 61b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "=r"(flag), "=&r"(tmp) 62b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "1"(addr), "ir"(size), 63b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "r"(current_thread_info()->addr_limit.seg), "0"(flag) 64b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "cc" 65b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ); 66b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 67b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells return flag; 68b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} 69b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 70b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __range_ok(addr, size) ___range_ok((unsigned long)(addr), (u32)(size)) 71b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 72b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0) 73b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __access_ok(addr, size) (__range_ok((addr), (size)) == 0) 74b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 75b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline int verify_area(int type, const void *addr, unsigned long size) 76b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{ 77b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells return access_ok(type, addr, size) ? 0 : -EFAULT; 78b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} 79b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 80b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 81b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* 82b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * The exception table consists of pairs of addresses: the first is the 83b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * address of an instruction that is allowed to fault, and the second is 84b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * the address at which the program should continue. No registers are 85b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * modified, so it is entirely up to the continuation code to figure out 86b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * what to do. 87b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * 88b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * All the routines below use bits of fixup code that are out of line 89b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * with the main instruction path. This means when everything is well, 90b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * we don't even have to jump over them. Further, they do not intrude 91b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * on our cache or tlb entries. 92b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */ 93b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 94b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstruct exception_table_entry 95b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{ 96b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells unsigned long insn, fixup; 97b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}; 98b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 99b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* Returns 0 if exception not found and fixup otherwise. */ 100b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern int fixup_exception(struct pt_regs *regs); 101b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 102b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define put_user(x, ptr) __put_user_check((x), (ptr), sizeof(*(ptr))) 103b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr))) 104b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 105b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* 106b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * The "__xxx" versions do not do address space checking, useful when 107b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * doing multiple accesses to the same area (the user has to do the 108b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * checks by hand with "access_ok()") 109b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */ 110b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __put_user(x, ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr))) 111b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr))) 112b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 113b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* 114b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * The "xxx_ret" versions return constant specified in third argument, if 115b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * something bad happens. These macros can be optimized for the 116b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * case of just returning from the function xxx_ret is used. 117b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */ 118b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 119b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define put_user_ret(x, ptr, ret) \ 120b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ({ if (put_user((x), (ptr))) return (ret); }) 121b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define get_user_ret(x, ptr, ret) \ 122b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ({ if (get_user((x), (ptr))) return (ret); }) 123b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __put_user_ret(x, ptr, ret) \ 124b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ({ if (__put_user((x), (ptr))) return (ret); }) 125b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __get_user_ret(x, ptr, ret) \ 126b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ({ if (__get_user((x), (ptr))) return (ret); }) 127b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 128b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstruct __large_struct { unsigned long buf[100]; }; 129b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __m(x) (*(struct __large_struct *)(x)) 130b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 131d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter#define __get_user_nocheck(x, ptr, size) \ 132d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter({ \ 133d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter unsigned long __gu_addr; \ 134d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter int __gu_err; \ 135d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter __gu_addr = (unsigned long) (ptr); \ 136d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter switch (size) { \ 137d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter case 1: { \ 138d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter unsigned char __gu_val; \ 139d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter __get_user_asm("bu"); \ 140d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter (x) = *(__force __typeof__(*(ptr))*) &__gu_val; \ 141d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter break; \ 142d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter } \ 143d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter case 2: { \ 144d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter unsigned short __gu_val; \ 145d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter __get_user_asm("hu"); \ 146d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter (x) = *(__force __typeof__(*(ptr))*) &__gu_val; \ 147d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter break; \ 148d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter } \ 149d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter case 4: { \ 150d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter unsigned int __gu_val; \ 151d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter __get_user_asm(""); \ 152d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter (x) = *(__force __typeof__(*(ptr))*) &__gu_val; \ 153d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter break; \ 154d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter } \ 155d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter default: \ 156d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter __get_user_unknown(); \ 157d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter break; \ 158d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter } \ 159d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter __gu_err; \ 160b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}) 161b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 162d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter#define __get_user_check(x, ptr, size) \ 163d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter({ \ 164c6dc9f0a4eeb7c014904475372c66e6d0ac5a572Akira Takeuchi const __typeof__(*(ptr))* __guc_ptr = (ptr); \ 165d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter int _e; \ 1666fc34436be2494c6fea63dc0759be9b360d9480aTkhai Kirill if (likely(__access_ok((unsigned long) __guc_ptr, (size)))) \ 1676fc34436be2494c6fea63dc0759be9b360d9480aTkhai Kirill _e = __get_user_nocheck((x), __guc_ptr, (size)); \ 168d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter else { \ 169d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter _e = -EFAULT; \ 170d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter (x) = (__typeof__(x))0; \ 171d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter } \ 172d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter _e; \ 173b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}) 174b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 175b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __get_user_asm(INSN) \ 176b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({ \ 177b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells asm volatile( \ 178b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "1:\n" \ 179b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " mov"INSN" %2,%1\n" \ 180b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " mov 0,%0\n" \ 181b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "2:\n" \ 182b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .section .fixup,\"ax\"\n" \ 183b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "3:\n\t" \ 184b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " mov %3,%0\n" \ 185b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " jmp 2b\n" \ 186b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .previous\n" \ 187b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .section __ex_table,\"a\"\n" \ 188b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .balign 4\n" \ 189b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .long 1b, 3b\n" \ 190b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .previous" \ 191b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "=&r" (__gu_err), "=&r" (__gu_val) \ 192b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "m" (__m(__gu_addr)), "i" (-EFAULT)); \ 193b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}) 194b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 195b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern int __get_user_unknown(void); 196b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 197b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __put_user_nocheck(x, ptr, size) \ 198b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({ \ 199b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells union { \ 200b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __typeof__(*(ptr)) val; \ 201b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells u32 bits[2]; \ 202b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells } __pu_val; \ 203b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells unsigned long __pu_addr; \ 204b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells int __pu_err; \ 205b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __pu_val.val = (x); \ 206b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __pu_addr = (unsigned long) (ptr); \ 207b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells switch (size) { \ 208b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells case 1: __put_user_asm("bu"); break; \ 209b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells case 2: __put_user_asm("hu"); break; \ 210b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells case 4: __put_user_asm("" ); break; \ 211b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells case 8: __put_user_asm8(); break; \ 212b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells default: __pu_err = __put_user_unknown(); break; \ 213b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells } \ 214b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __pu_err; \ 215b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}) 216b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 217b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __put_user_check(x, ptr, size) \ 218b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({ \ 219b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells union { \ 220b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __typeof__(*(ptr)) val; \ 221b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells u32 bits[2]; \ 222b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells } __pu_val; \ 223b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells unsigned long __pu_addr; \ 224b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells int __pu_err; \ 225b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __pu_val.val = (x); \ 226b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __pu_addr = (unsigned long) (ptr); \ 227b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells if (likely(__access_ok(__pu_addr, size))) { \ 228b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells switch (size) { \ 229b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells case 1: __put_user_asm("bu"); break; \ 230b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells case 2: __put_user_asm("hu"); break; \ 231b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells case 4: __put_user_asm("" ); break; \ 232b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells case 8: __put_user_asm8(); break; \ 233b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells default: __pu_err = __put_user_unknown(); break; \ 234b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells } \ 235b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells } \ 236b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells else { \ 237b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __pu_err = -EFAULT; \ 238b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells } \ 239b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __pu_err; \ 240b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}) 241b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 242b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __put_user_asm(INSN) \ 243b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({ \ 244b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells asm volatile( \ 245b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "1:\n" \ 246b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " mov"INSN" %1,%2\n" \ 247b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " mov 0,%0\n" \ 248b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "2:\n" \ 249b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .section .fixup,\"ax\"\n" \ 250b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "3:\n" \ 251b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " mov %3,%0\n" \ 252b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " jmp 2b\n" \ 253b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .previous\n" \ 254b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .section __ex_table,\"a\"\n" \ 255b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .balign 4\n" \ 256b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .long 1b, 3b\n" \ 257b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .previous" \ 258b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "=&r" (__pu_err) \ 259b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "r" (__pu_val.val), "m" (__m(__pu_addr)), \ 260b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "i" (-EFAULT) \ 261b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ); \ 262b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}) 263b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 264b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __put_user_asm8() \ 265b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({ \ 266b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells asm volatile( \ 267b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "1: mov %1,%3 \n" \ 268b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "2: mov %2,%4 \n" \ 269b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " mov 0,%0 \n" \ 270b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "3: \n" \ 271b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .section .fixup,\"ax\" \n" \ 272b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "4: \n" \ 273b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " mov %5,%0 \n" \ 27454b71fba68efbf3ab89721a384df2ce757750979Akira Takeuchi " jmp 3b \n" \ 275b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .previous \n" \ 276b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .section __ex_table,\"a\"\n" \ 277b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .balign 4 \n" \ 278b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .long 1b, 4b \n" \ 279b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .long 2b, 4b \n" \ 280b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .previous \n" \ 281b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "=&r" (__pu_err) \ 282b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "r" (__pu_val.bits[0]), "r" (__pu_val.bits[1]), \ 283b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "m" (__m(__pu_addr)), "m" (__m(__pu_addr+4)), \ 284b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "i" (-EFAULT) \ 285b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ); \ 286b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}) 287b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 288b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern int __put_user_unknown(void); 289b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 290b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 291b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* 292b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * Copy To/From Userspace 293b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */ 294b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* Generic arbitrary sized copy. */ 295b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __copy_user(to, from, size) \ 296b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsdo { \ 297b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells if (size) { \ 298b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells void *__to = to; \ 299b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells const void *__from = from; \ 300b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells int w; \ 301b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells asm volatile( \ 302b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "0: movbu (%0),%3;\n" \ 303b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "1: movbu %3,(%1);\n" \ 304b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " inc %0;\n" \ 305b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " inc %1;\n" \ 306b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " add -1,%2;\n" \ 307b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " bne 0b;\n" \ 308b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "2:\n" \ 309b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .section .fixup,\"ax\"\n" \ 310b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "3: jmp 2b\n" \ 311b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .previous\n" \ 312b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .section __ex_table,\"a\"\n" \ 313b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .balign 4\n" \ 314b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .long 0b,3b\n" \ 315b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .long 1b,3b\n" \ 316b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .previous\n" \ 317b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\ 318b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "0"(__from), "1"(__to), "2"(size) \ 319d6bb7a1ad326f56f0793353c59348554f84b513cMark Salter : "cc", "memory"); \ 320b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells } \ 321b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} while (0) 322b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 323b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __copy_user_zeroing(to, from, size) \ 324b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsdo { \ 325b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells if (size) { \ 326b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells void *__to = to; \ 327b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells const void *__from = from; \ 328b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells int w; \ 329b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells asm volatile( \ 330b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "0: movbu (%0),%3;\n" \ 331b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "1: movbu %3,(%1);\n" \ 332b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " inc %0;\n" \ 333b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " inc %1;\n" \ 334b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " add -1,%2;\n" \ 335b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " bne 0b;\n" \ 336b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "2:\n" \ 337b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .section .fixup,\"ax\"\n" \ 338b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "3:\n" \ 339b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " mov %2,%0\n" \ 340b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " clr %3\n" \ 341b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "4: movbu %3,(%1);\n" \ 342b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " inc %1;\n" \ 343b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " add -1,%2;\n" \ 344b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " bne 4b;\n" \ 345b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " mov %0,%2\n" \ 346b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " jmp 2b\n" \ 347b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .previous\n" \ 348b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .section __ex_table,\"a\"\n" \ 349b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .balign 4\n" \ 350b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .long 0b,3b\n" \ 351b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .long 1b,3b\n" \ 352b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .previous\n" \ 353b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\ 354b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "0"(__from), "1"(__to), "2"(size) \ 355d6bb7a1ad326f56f0793353c59348554f84b513cMark Salter : "cc", "memory"); \ 356b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells } \ 357b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} while (0) 358b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 359b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* We let the __ versions of copy_from/to_user inline, because they're often 360b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * used in fast paths and have only a small space overhead. 361b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */ 362b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline 363b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsunsigned long __generic_copy_from_user_nocheck(void *to, const void *from, 364b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells unsigned long n) 365b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{ 366b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __copy_user_zeroing(to, from, n); 367b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells return n; 368b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} 369b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 370b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline 371b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsunsigned long __generic_copy_to_user_nocheck(void *to, const void *from, 372b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells unsigned long n) 373b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{ 374b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __copy_user(to, from, n); 375b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells return n; 376b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} 377b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 378b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 379b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#if 0 380368dd5acd154b09c043cc4392a74da01599b37d5Akira Takeuchi#error "don't use - these macros don't increment to & from pointers" 381b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* Optimize just a little bit when we know the size of the move. */ 382b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __constant_copy_user(to, from, size) \ 383b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsdo { \ 384b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells asm volatile( \ 385b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " mov %0,a0;\n" \ 386b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "0: movbu (%1),d3;\n" \ 387b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "1: movbu d3,(%2);\n" \ 388b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " add -1,a0;\n" \ 389b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " bne 0b;\n" \ 390b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "2:;" \ 391b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ".section .fixup,\"ax\"\n" \ 392b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "3: jmp 2b\n" \ 393b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ".previous\n" \ 394b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ".section __ex_table,\"a\"\n" \ 395b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .balign 4\n" \ 396b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .long 0b,3b\n" \ 397b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .long 1b,3b\n" \ 398b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ".previous" \ 399b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : \ 400b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "d"(size), "d"(to), "d"(from) \ 401b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "d3", "a0"); \ 402b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} while (0) 403b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 404b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* Optimize just a little bit when we know the size of the move. */ 405b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __constant_copy_user_zeroing(to, from, size) \ 406b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsdo { \ 407b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells asm volatile( \ 408b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " mov %0,a0;\n" \ 409b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "0: movbu (%1),d3;\n" \ 410b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "1: movbu d3,(%2);\n" \ 411b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " add -1,a0;\n" \ 412b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " bne 0b;\n" \ 413b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "2:;" \ 414b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ".section .fixup,\"ax\"\n" \ 415b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells "3: jmp 2b\n" \ 416b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ".previous\n" \ 417b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ".section __ex_table,\"a\"\n" \ 418b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .balign 4\n" \ 419b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .long 0b,3b\n" \ 420b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells " .long 1b,3b\n" \ 421b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells ".previous" \ 422b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : \ 423b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "d"(size), "d"(to), "d"(from) \ 424b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells : "d3", "a0"); \ 425b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} while (0) 426b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 427b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline 428b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsunsigned long __constant_copy_to_user(void *to, const void *from, 429b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells unsigned long n) 430b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{ 431b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells if (access_ok(VERIFY_WRITE, to, n)) 432b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __constant_copy_user(to, from, n); 433b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells return n; 434b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} 435b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 436b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline 437b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsunsigned long __constant_copy_from_user(void *to, const void *from, 438b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells unsigned long n) 439b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{ 440b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells if (access_ok(VERIFY_READ, from, n)) 441b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __constant_copy_user_zeroing(to, from, n); 442b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells return n; 443b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} 444b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 445b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline 446b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsunsigned long __constant_copy_to_user_nocheck(void *to, const void *from, 447b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells unsigned long n) 448b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{ 449b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __constant_copy_user(to, from, n); 450b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells return n; 451b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} 452b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 453b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline 454b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsunsigned long __constant_copy_from_user_nocheck(void *to, const void *from, 455b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells unsigned long n) 456b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{ 457b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __constant_copy_user_zeroing(to, from, n); 458b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells return n; 459b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} 460b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#endif 461b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 462b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern unsigned long __generic_copy_to_user(void __user *, const void *, 463b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells unsigned long); 464b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern unsigned long __generic_copy_from_user(void *, const void __user *, 465b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells unsigned long); 466b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 467b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __copy_to_user_inatomic(to, from, n) \ 468b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __generic_copy_to_user_nocheck((to), (from), (n)) 469b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __copy_from_user_inatomic(to, from, n) \ 470b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __generic_copy_from_user_nocheck((to), (from), (n)) 471b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 472b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __copy_to_user(to, from, n) \ 473b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({ \ 474b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells might_sleep(); \ 475b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __copy_to_user_inatomic((to), (from), (n)); \ 476b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}) 477b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 478b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __copy_from_user(to, from, n) \ 479b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({ \ 480b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells might_sleep(); \ 481b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells __copy_from_user_inatomic((to), (from), (n)); \ 482b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}) 483b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 484b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 485b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define copy_to_user(to, from, n) __generic_copy_to_user((to), (from), (n)) 486b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n)) 487b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 488b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern long strncpy_from_user(char *dst, const char __user *src, long count); 489b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern long __strncpy_from_user(char *dst, const char __user *src, long count); 490b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern long strnlen_user(const char __user *str, long n); 491b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define strlen_user(str) strnlen_user(str, ~0UL >> 1) 492b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern unsigned long clear_user(void __user *mem, unsigned long len); 493b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern unsigned long __clear_user(void __user *mem, unsigned long len); 494b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells 495b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#endif /* _ASM_UACCESS_H */ 496