1/* 2 * linux/include/asm-arm/proc-armo/segment.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/* 21 * These are the values used to represent the user `fs' and the kernel `ds' 22 */ 23#define KERNEL_DS 0x03000000 24#define USER_DS 0x02000000 25 26extern uaccess_t uaccess_user, uaccess_kernel; 27 28static inline void set_fs (mm_segment_t fs) 29{ 30 current->addr_limit = fs; 31 current->thread.uaccess = fs == USER_DS ? &uaccess_user : &uaccess_kernel; 32} 33 34#define __range_ok(addr,size) ({ \ 35 unsigned long flag, sum; \ 36 __asm__ __volatile__("subs %1, %0, %3; cmpcs %1, %2; movcs %0, #0" \ 37 : "=&r" (flag), "=&r" (sum) \ 38 : "r" (addr), "Ir" (size), "0" (current->addr_limit) \ 39 : "cc"); \ 40 flag; }) 41 42#define __addr_ok(addr) ({ \ 43 unsigned long flag; \ 44 __asm__ __volatile__("cmp %2, %0; movlo %0, #0" \ 45 : "=&r" (flag) \ 46 : "0" (current->addr_limit), "r" (addr) \ 47 : "cc"); \ 48 (flag == 0); }) 49 50#define __put_user_asm_byte(x,addr,err) \ 51 __asm__ __volatile__( \ 52 " mov r0, %1\n" \ 53 " mov r1, %2\n" \ 54 " mov r2, %0\n" \ 55 " mov lr, pc\n" \ 56 " mov pc, %3\n" \ 57 " mov %0, r2\n" \ 58 : "=r" (err) \ 59 : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_byte), \ 60 "0" (err) \ 61 : "r0", "r1", "r2", "lr") 62 63#define __put_user_asm_half(x,addr,err) \ 64 __asm__ __volatile__( \ 65 " mov r0, %1\n" \ 66 " mov r1, %2\n" \ 67 " mov r2, %0\n" \ 68 " mov lr, pc\n" \ 69 " mov pc, %3\n" \ 70 " mov %0, r2\n" \ 71 : "=r" (err) \ 72 : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_half), \ 73 "0" (err) \ 74 : "r0", "r1", "r2", "lr") 75 76#define __put_user_asm_word(x,addr,err) \ 77 __asm__ __volatile__( \ 78 " mov r0, %1\n" \ 79 " mov r1, %2\n" \ 80 " mov r2, %0\n" \ 81 " mov lr, pc\n" \ 82 " mov pc, %3\n" \ 83 " mov %0, r2\n" \ 84 : "=r" (err) \ 85 : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_word), \ 86 "0" (err) \ 87 : "r0", "r1", "r2", "lr") 88 89#define __get_user_asm_byte(x,addr,err) \ 90 __asm__ __volatile__( \ 91 " mov r0, %2\n" \ 92 " mov r1, %0\n" \ 93 " mov lr, pc\n" \ 94 " mov pc, %3\n" \ 95 " mov %0, r1\n" \ 96 " mov %1, r0\n" \ 97 : "=r" (err), "=r" (x) \ 98 : "r" (addr), "r" (current->thread.uaccess->get_byte), "0" (err) \ 99 : "r0", "r1", "r2", "lr") 100 101#define __get_user_asm_half(x,addr,err) \ 102 __asm__ __volatile__( \ 103 " mov r0, %2\n" \ 104 " mov r1, %0\n" \ 105 " mov lr, pc\n" \ 106 " mov pc, %3\n" \ 107 " mov %0, r1\n" \ 108 " mov %1, r0\n" \ 109 : "=r" (err), "=r" (x) \ 110 : "r" (addr), "r" (current->thread.uaccess->get_half), "0" (err) \ 111 : "r0", "r1", "r2", "lr") 112 113#define __get_user_asm_word(x,addr,err) \ 114 __asm__ __volatile__( \ 115 " mov r0, %2\n" \ 116 " mov r1, %0\n" \ 117 " mov lr, pc\n" \ 118 " mov pc, %3\n" \ 119 " mov %0, r1\n" \ 120 " mov %1, r0\n" \ 121 : "=r" (err), "=r" (x) \ 122 : "r" (addr), "r" (current->thread.uaccess->get_word), "0" (err) \ 123 : "r0", "r1", "r2", "lr") 124 125#define __do_copy_from_user(to,from,n) \ 126 (n) = current->thread.uaccess->copy_from_user((to),(from),(n)) 127 128#define __do_copy_to_user(to,from,n) \ 129 (n) = current->thread.uaccess->copy_to_user((to),(from),(n)) 130 131#define __do_clear_user(addr,sz) \ 132 (sz) = current->thread.uaccess->clear_user((addr),(sz)) 133 134#define __do_strncpy_from_user(dst,src,count,res) \ 135 (res) = current->thread.uaccess->strncpy_from_user(dst,src,count) 136 137#define __do_strnlen_user(s,n,res) \ 138 (res) = current->thread.uaccess->strnlen_user(s,n) 139