1c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 2c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * linux/include/asm-arm/uaccess.h 3c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 4c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * This program is free software; you can redistribute it and/or modify 5c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * it under the terms of the GNU General Public License version 2 as 6c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * published by the Free Software Foundation. 7c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 8c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef _ASMARM_UACCESS_H 9c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define _ASMARM_UACCESS_H 10c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 11c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 12c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * User space memory access functions 13c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 14c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/sched.h> 15c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/errno.h> 16c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/memory.h> 17c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/domain.h> 18c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/system.h> 19c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 20c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define VERIFY_READ 0 21c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define VERIFY_WRITE 1 22c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 23c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 24c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * The exception table consists of pairs of addresses: the first is the 25c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * address of an instruction that is allowed to fault, and the second is 26c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * the address at which the program should continue. No registers are 27c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * modified, so it is entirely up to the continuation code to figure out 28c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * what to do. 29c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 30c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * All the routines below use bits of fixup code that are out of line 31c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * with the main instruction path. This means when everything is well, 32c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * we don't even have to jump over them. Further, they do not intrude 33c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * on our cache or tlb entries. 34c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 35c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 36c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustruct exception_table_entry 37c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 38c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long insn, fixup; 39c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}; 40c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 41c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int fixup_exception(struct pt_regs *regs); 42c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 43c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 44c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * These two are intentionally not defined anywhere - if the kernel 45c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * code generates any references to them, that's a bug. 46c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 47c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __get_user_bad(void); 48c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __put_user_bad(void); 49c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 50c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 51c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Note that this is actually 0x1,0000,0000 52c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 53c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define KERNEL_DS 0x00000000 54c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define get_ds() (KERNEL_DS) 55c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 56c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MMU 57c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 58c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define USER_DS TASK_SIZE 59c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define get_fs() (current_thread_info()->addr_limit) 60c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 61c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void set_fs(mm_segment_t fs) 62c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 63c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru current_thread_info()->addr_limit = fs; 64c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER); 65c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 66c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 67c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define segment_eq(a,b) ((a) == (b)) 68c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 69c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __addr_ok(addr) ({ \ 70c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long flag; \ 71c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__("cmp %2, %0; movlo %0, #0" \ 72c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (flag) \ 73c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "0" (current_thread_info()->addr_limit), "r" (addr) \ 74c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc"); \ 75c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru (flag == 0); }) 76c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 77c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* We use 33-bit arithmetic here... */ 78c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __range_ok(addr,size) ({ \ 79c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long flag, sum; \ 80c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __chk_user_ptr(addr); \ 81c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \ 82c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (flag), "=&r" (sum) \ 83c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \ 84c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc"); \ 85c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru flag; }) 86c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 87c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 88c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Single-value transfer routines. They automatically use the right 89c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * size if we just have the right pointer type. Note that the functions 90c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * which read from user space (*get_*) need to take care not to leak 91c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * kernel data even if the calling code is buggy and fails to check 92c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * the return value. This means zeroing out the destination variable 93c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * or buffer on error. Normally this is done out of line by the 94c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * fixup code, but there are a few places where it intrudes on the 95c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * main code path. When we only write to user space, there is no 96c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * problem. 97c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 98c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __get_user_1(void *); 99c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __get_user_2(void *); 100c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __get_user_4(void *); 101c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 102c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_x(__r2,__p,__e,__s,__i...) \ 103c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__ ( \ 104c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asmeq("%0", "r0") __asmeq("%1", "r2") \ 105c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "bl __get_user_" #__s \ 106c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (__e), "=r" (__r2) \ 107c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "0" (__p) \ 108c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : __i, "cc") 109c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 110c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define get_user(x,p) \ 111c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ({ \ 112c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru const register typeof(*(p)) __user *__p asm("r0") = (p);\ 113c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru register unsigned int __r2 asm("r2"); \ 114c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru register int __e asm("r0"); \ 115c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru switch (sizeof(*(__p))) { \ 116c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 1: \ 117c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __get_user_x(__r2, __p, __e, 1, "lr"); \ 118c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; \ 119c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 2: \ 120c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __get_user_x(__r2, __p, __e, 2, "r3", "lr"); \ 121c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; \ 122c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 4: \ 123c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __get_user_x(__r2, __p, __e, 4, "lr"); \ 124c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; \ 125c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru default: __e = __get_user_bad(); break; \ 126c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru } \ 127c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru x = (typeof(*(p))) __r2; \ 128c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __e; \ 129c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru }) 130c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 131c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __put_user_1(void *, unsigned int); 132c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __put_user_2(void *, unsigned int); 133c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __put_user_4(void *, unsigned int); 134c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __put_user_8(void *, unsigned long long); 135c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 136c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_x(__r2,__p,__e,__s) \ 137c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__ ( \ 138c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asmeq("%0", "r0") __asmeq("%2", "r2") \ 139c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "bl __put_user_" #__s \ 140c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (__e) \ 141c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "0" (__p), "r" (__r2) \ 142c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "ip", "lr", "cc") 143c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 144c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define put_user(x,p) \ 145c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ({ \ 146c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru const register typeof(*(p)) __r2 asm("r2") = (x); \ 147c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru const register typeof(*(p)) __user *__p asm("r0") = (p);\ 148c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru register int __e asm("r0"); \ 149c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru switch (sizeof(*(__p))) { \ 150c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 1: \ 151c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __put_user_x(__r2, __p, __e, 1); \ 152c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; \ 153c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 2: \ 154c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __put_user_x(__r2, __p, __e, 2); \ 155c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; \ 156c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 4: \ 157c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __put_user_x(__r2, __p, __e, 4); \ 158c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; \ 159c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 8: \ 160c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __put_user_x(__r2, __p, __e, 8); \ 161c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; \ 162c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru default: __e = __put_user_bad(); break; \ 163c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru } \ 164c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __e; \ 165c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru }) 166c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 167c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else /* CONFIG_MMU */ 168c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 169c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 170c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * uClinux has only one addr space, so has simplified address limits. 171c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 172c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define USER_DS KERNEL_DS 173c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 174c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define segment_eq(a,b) (1) 175c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __addr_ok(addr) (1) 176c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __range_ok(addr,size) (0) 177c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define get_fs() (KERNEL_DS) 178c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 179c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void set_fs(mm_segment_t fs) 180c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 181c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 182c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 183c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define get_user(x,p) __get_user(x,p) 184c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define put_user(x,p) __put_user(x,p) 185c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 186c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* CONFIG_MMU */ 187c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 188c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define access_ok(type,addr,size) (__range_ok(addr,size) == 0) 189c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 190c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 191c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * The "__xxx" versions of the user access functions do not verify the 192c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * address space - it must have been done previously with a separate 193c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * "access_ok()" call. 194c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 195c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * The "xxx_error" versions set the third argument to EFAULT if an 196c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * error occurs, and leave it unchanged on success. Note that these 197c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * versions are void (ie, don't return a value as such). 198c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 199c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user(x,ptr) \ 200c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({ \ 201c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru long __gu_err = 0; \ 202c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __get_user_err((x),(ptr),__gu_err); \ 203c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __gu_err; \ 204c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}) 205c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 206c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_error(x,ptr,err) \ 207c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({ \ 208c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __get_user_err((x),(ptr),err); \ 209c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru (void) 0; \ 210c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}) 211c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 212c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_err(x,ptr,err) \ 213c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querudo { \ 214c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long __gu_addr = (unsigned long)(ptr); \ 215c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long __gu_val; \ 216c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __chk_user_ptr(ptr); \ 217c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru switch (sizeof(*(ptr))) { \ 218c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \ 219c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \ 220c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 4: __get_user_asm_word(__gu_val,__gu_addr,err); break; \ 221c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru default: (__gu_val) = __get_user_bad(); \ 222c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru } \ 223c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru (x) = (__typeof__(*(ptr)))__gu_val; \ 224c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} while (0) 225c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 226c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_asm_byte(x,addr,err) \ 227c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 228c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "1: ldrbt %1,[%2],#0\n" \ 229c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "2:\n" \ 230c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .section .fixup,\"ax\"\n" \ 231c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .align 2\n" \ 232c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "3: mov %0, %3\n" \ 233c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " mov %1, #0\n" \ 234c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " b 2b\n" \ 235c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .previous\n" \ 236c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .section __ex_table,\"a\"\n" \ 237c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .align 3\n" \ 238c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .long 1b, 3b\n" \ 239c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .previous" \ 240c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "+r" (err), "=&r" (x) \ 241c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (addr), "i" (-EFAULT) \ 242c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc") 243c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 244c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ARMEB__ 245c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_asm_half(x,__gu_addr,err) \ 246c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({ \ 247c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long __b1, __b2; \ 248c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __get_user_asm_byte(__b1, __gu_addr, err); \ 249c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __get_user_asm_byte(__b2, __gu_addr + 1, err); \ 250c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru (x) = __b1 | (__b2 << 8); \ 251c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}) 252c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 253c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_asm_half(x,__gu_addr,err) \ 254c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({ \ 255c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long __b1, __b2; \ 256c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __get_user_asm_byte(__b1, __gu_addr, err); \ 257c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __get_user_asm_byte(__b2, __gu_addr + 1, err); \ 258c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru (x) = (__b1 << 8) | __b2; \ 259c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}) 260c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 261c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 262c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_asm_word(x,addr,err) \ 263c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 264c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "1: ldrt %1,[%2],#0\n" \ 265c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "2:\n" \ 266c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .section .fixup,\"ax\"\n" \ 267c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .align 2\n" \ 268c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "3: mov %0, %3\n" \ 269c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " mov %1, #0\n" \ 270c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " b 2b\n" \ 271c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .previous\n" \ 272c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .section __ex_table,\"a\"\n" \ 273c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .align 3\n" \ 274c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .long 1b, 3b\n" \ 275c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .previous" \ 276c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "+r" (err), "=&r" (x) \ 277c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (addr), "i" (-EFAULT) \ 278c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc") 279c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 280c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user(x,ptr) \ 281c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({ \ 282c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru long __pu_err = 0; \ 283c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __put_user_err((x),(ptr),__pu_err); \ 284c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __pu_err; \ 285c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}) 286c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 287c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_error(x,ptr,err) \ 288c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({ \ 289c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __put_user_err((x),(ptr),err); \ 290c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru (void) 0; \ 291c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}) 292c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 293c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_err(x,ptr,err) \ 294c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querudo { \ 295c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long __pu_addr = (unsigned long)(ptr); \ 296c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __typeof__(*(ptr)) __pu_val = (x); \ 297c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __chk_user_ptr(ptr); \ 298c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru switch (sizeof(*(ptr))) { \ 299c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \ 300c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \ 301c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 4: __put_user_asm_word(__pu_val,__pu_addr,err); break; \ 302c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 8: __put_user_asm_dword(__pu_val,__pu_addr,err); break; \ 303c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru default: __put_user_bad(); \ 304c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru } \ 305c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} while (0) 306c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 307c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_asm_byte(x,__pu_addr,err) \ 308c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 309c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "1: strbt %1,[%2],#0\n" \ 310c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "2:\n" \ 311c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .section .fixup,\"ax\"\n" \ 312c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .align 2\n" \ 313c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "3: mov %0, %3\n" \ 314c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " b 2b\n" \ 315c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .previous\n" \ 316c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .section __ex_table,\"a\"\n" \ 317c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .align 3\n" \ 318c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .long 1b, 3b\n" \ 319c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .previous" \ 320c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "+r" (err) \ 321c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ 322c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc") 323c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 324c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ARMEB__ 325c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_asm_half(x,__pu_addr,err) \ 326c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({ \ 327c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long __temp = (unsigned long)(x); \ 328c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __put_user_asm_byte(__temp, __pu_addr, err); \ 329c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \ 330c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}) 331c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 332c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_asm_half(x,__pu_addr,err) \ 333c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({ \ 334c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long __temp = (unsigned long)(x); \ 335c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __put_user_asm_byte(__temp >> 8, __pu_addr, err); \ 336c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __put_user_asm_byte(__temp, __pu_addr + 1, err); \ 337c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}) 338c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 339c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 340c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_asm_word(x,__pu_addr,err) \ 341c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 342c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "1: strt %1,[%2],#0\n" \ 343c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "2:\n" \ 344c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .section .fixup,\"ax\"\n" \ 345c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .align 2\n" \ 346c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "3: mov %0, %3\n" \ 347c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " b 2b\n" \ 348c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .previous\n" \ 349c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .section __ex_table,\"a\"\n" \ 350c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .align 3\n" \ 351c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .long 1b, 3b\n" \ 352c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .previous" \ 353c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "+r" (err) \ 354c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ 355c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc") 356c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 357c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ARMEB__ 358c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __reg_oper0 "%R2" 359c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __reg_oper1 "%Q2" 360c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 361c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __reg_oper0 "%Q2" 362c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __reg_oper1 "%R2" 363c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 364c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 365c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_asm_dword(x,__pu_addr,err) \ 366c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 367c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "1: strt " __reg_oper1 ", [%1], #4\n" \ 368c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "2: strt " __reg_oper0 ", [%1], #0\n" \ 369c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "3:\n" \ 370c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .section .fixup,\"ax\"\n" \ 371c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .align 2\n" \ 372c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "4: mov %0, %3\n" \ 373c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " b 3b\n" \ 374c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .previous\n" \ 375c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .section __ex_table,\"a\"\n" \ 376c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .align 3\n" \ 377c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .long 1b, 4b\n" \ 378c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .long 2b, 4b\n" \ 379c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " .previous" \ 380c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "+r" (err), "+r" (__pu_addr) \ 381c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (x), "i" (-EFAULT) \ 382c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc") 383c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 384c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 385c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MMU 386c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n); 387c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n); 388c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned long __clear_user(void __user *addr, unsigned long n); 389c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 390c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __copy_from_user(to,from,n) (memcpy(to, (void __force *)from, n), 0) 391c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __copy_to_user(to,from,n) (memcpy((void __force *)to, from, n), 0) 392c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __clear_user(addr,n) (memset((void __force *)addr, 0, n), 0) 393c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 394c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 395c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned long __strncpy_from_user(char *to, const char __user *from, unsigned long count); 396c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned long __strnlen_user(const char __user *s, long n); 397c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 398c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) 399c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 400c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru if (access_ok(VERIFY_READ, from, n)) 401c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru n = __copy_from_user(to, from, n); 402c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru else /* security hole - plug it */ 403c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru memzero(to, n); 404c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return n; 405c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 406c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 407c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) 408c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 409c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru if (access_ok(VERIFY_WRITE, to, n)) 410c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru n = __copy_to_user(to, from, n); 411c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return n; 412c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 413c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 414c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __copy_to_user_inatomic __copy_to_user 415c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __copy_from_user_inatomic __copy_from_user 416c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 417c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline unsigned long clear_user(void __user *to, unsigned long n) 418c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 419c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru if (access_ok(VERIFY_WRITE, to, n)) 420c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru n = __clear_user(to, n); 421c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return n; 422c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 423c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 424c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline long strncpy_from_user(char *dst, const char __user *src, long count) 425c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 426c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru long res = -EFAULT; 427c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru if (access_ok(VERIFY_READ, src, 1)) 428c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru res = __strncpy_from_user(dst, src, count); 429c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return res; 430c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 431c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 432c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define strlen_user(s) strnlen_user(s, ~0UL >> 1) 433c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 434c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline long strnlen_user(const char __user *s, long n) 435c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 436c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long res = 0; 437c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 438c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru if (__addr_ok(s)) 439c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru res = __strnlen_user(s, n); 440c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 441c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return res; 442c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 443c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 444c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* _ASMARM_UACCESS_H */ 445