1/* 2 * linux/include/asm-arm/proc-armo/uaccess.h 3 * 4 * Copyright (C) 1996 Russell King 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 11/* 12 * The fs functions are implemented on the ARM2 and ARM3 architectures 13 * manually. 14 * Use *_user functions to access user memory with faulting behaving 15 * as though the user is accessing the memory. 16 * Use set_fs(get_ds()) and then the *_user functions to allow them to 17 * access kernel memory. 18 */ 19 20#define KERNEL_DS 0x03FFFFFF 21#define USER_DS 0x02000000 22 23extern uaccess_t uaccess_user, uaccess_kernel; 24 25static inline void set_fs (mm_segment_t fs) 26{ 27 current_thread_info()->addr_limit = fs; 28 current->thread.uaccess = (fs == USER_DS ? &uaccess_user : &uaccess_kernel); 29} 30 31#define __range_ok(addr,size) ({ \ 32 unsigned long flag, roksum; \ 33 __asm__ __volatile__("subs %1, %0, %3; cmpcs %1, %2; movcs %0, #0" \ 34 : "=&r" (flag), "=&r" (roksum) \ 35 : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \ 36 : "cc"); \ 37 flag; }) 38 39#define __addr_ok(addr) ({ \ 40 unsigned long flag; \ 41 __asm__ __volatile__("cmp %2, %0; movlo %0, #0" \ 42 : "=&r" (flag) \ 43 : "0" (current_thread_info()->addr_limit), "r" (addr) \ 44 : "cc"); \ 45 (flag == 0); }) 46 47#define __put_user_asm_byte(x,addr,err) \ 48 __asm__ __volatile__( \ 49 " mov r0, %1\n" \ 50 " mov r1, %2\n" \ 51 " mov r2, %0\n" \ 52 " mov lr, pc\n" \ 53 " mov pc, %3\n" \ 54 " mov %0, r2\n" \ 55 : "=r" (err) \ 56 : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_byte), \ 57 "0" (err) \ 58 : "r0", "r1", "r2", "lr") 59 60#define __put_user_asm_half(x,addr,err) \ 61 __asm__ __volatile__( \ 62 " mov r0, %1\n" \ 63 " mov r1, %2\n" \ 64 " mov r2, %0\n" \ 65 " mov lr, pc\n" \ 66 " mov pc, %3\n" \ 67 " mov %0, r2\n" \ 68 : "=r" (err) \ 69 : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_half), \ 70 "0" (err) \ 71 : "r0", "r1", "r2", "lr") 72 73#define __put_user_asm_word(x,addr,err) \ 74 __asm__ __volatile__( \ 75 " mov r0, %1\n" \ 76 " mov r1, %2\n" \ 77 " mov r2, %0\n" \ 78 " mov lr, pc\n" \ 79 " mov pc, %3\n" \ 80 " mov %0, r2\n" \ 81 : "=r" (err) \ 82 : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_word), \ 83 "0" (err) \ 84 : "r0", "r1", "r2", "lr") 85 86#define __put_user_asm_dword(x,addr,err) \ 87 __asm__ __volatile__( \ 88 " mov r0, %1\n" \ 89 " mov r1, %2\n" \ 90 " mov r2, %0\n" \ 91 " mov lr, pc\n" \ 92 " mov pc, %3\n" \ 93 " mov %0, r2\n" \ 94 : "=r" (err) \ 95 : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_dword), \ 96 "0" (err) \ 97 : "r0", "r1", "r2", "lr") 98 99#define __get_user_asm_byte(x,addr,err) \ 100 __asm__ __volatile__( \ 101 " mov r0, %2\n" \ 102 " mov r1, %0\n" \ 103 " mov lr, pc\n" \ 104 " mov pc, %3\n" \ 105 " mov %0, r1\n" \ 106 " mov %1, r0\n" \ 107 : "=r" (err), "=r" (x) \ 108 : "r" (addr), "r" (current->thread.uaccess->get_byte), "0" (err) \ 109 : "r0", "r1", "r2", "lr") 110 111#define __get_user_asm_half(x,addr,err) \ 112 __asm__ __volatile__( \ 113 " mov r0, %2\n" \ 114 " mov r1, %0\n" \ 115 " mov lr, pc\n" \ 116 " mov pc, %3\n" \ 117 " mov %0, r1\n" \ 118 " mov %1, r0\n" \ 119 : "=r" (err), "=r" (x) \ 120 : "r" (addr), "r" (current->thread.uaccess->get_half), "0" (err) \ 121 : "r0", "r1", "r2", "lr") 122 123#define __get_user_asm_word(x,addr,err) \ 124 __asm__ __volatile__( \ 125 " mov r0, %2\n" \ 126 " mov r1, %0\n" \ 127 " mov lr, pc\n" \ 128 " mov pc, %3\n" \ 129 " mov %0, r1\n" \ 130 " mov %1, r0\n" \ 131 : "=r" (err), "=r" (x) \ 132 : "r" (addr), "r" (current->thread.uaccess->get_word), "0" (err) \ 133 : "r0", "r1", "r2", "lr") 134 135#define __do_copy_from_user(to,from,n) \ 136 (n) = current->thread.uaccess->copy_from_user((to),(from),(n)) 137 138#define __do_copy_to_user(to,from,n) \ 139 (n) = current->thread.uaccess->copy_to_user((to),(from),(n)) 140 141#define __do_clear_user(addr,sz) \ 142 (sz) = current->thread.uaccess->clear_user((addr),(sz)) 143 144#define __do_strncpy_from_user(dst,src,count,res) \ 145 (res) = current->thread.uaccess->strncpy_from_user(dst,src,count) 146 147#define __do_strnlen_user(s,n,res) \ 148 (res) = current->thread.uaccess->strnlen_user(s,n) 149