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