~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/asm-parisc/uaccess.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #ifndef __PARISC_UACCESS_H
  2 #define __PARISC_UACCESS_H
  3 
  4 /*
  5  * User space memory access functions
  6  */
  7 #include <linux/sched.h>
  8 #include <asm/page.h>
  9 #include <asm/system.h>
 10 #include <asm/cache.h>
 11 
 12 #define VERIFY_READ 0
 13 #define VERIFY_WRITE 1
 14 
 15 #define KERNEL_DS       ((mm_segment_t){0})
 16 #define USER_DS         ((mm_segment_t){1})
 17 
 18 #define segment_eq(a,b) ((a).seg == (b).seg)
 19 
 20 #define get_ds()        (KERNEL_DS)
 21 #define get_fs()        (current->addr_limit)
 22 #define set_fs(x)       (current->addr_limit = (x))
 23 
 24 /*
 25  * Note that since kernel addresses are in a separate address space on
 26  * parisc, we don't need to do anything for access_ok() or verify_area().
 27  * We just let the page fault handler do the right thing. This also means
 28  * that put_user is the same as __put_user, etc.
 29  */
 30 
 31 #define access_ok(type,addr,size)   (1)
 32 #define verify_area(type,addr,size) (0)
 33 
 34 #define put_user __put_user
 35 #define get_user __get_user
 36 
 37 /*
 38  * The exception table contains two values: the first is an address
 39  * for an instruction that is allowed to fault, and the second is
 40  * the number of bytes to skip if a fault occurs. We also support in
 41  * two bit flags: 0x2 tells the exception handler to clear register
 42  * r9 and 0x1 tells the exception handler to put -EFAULT in r8.
 43  * This allows us to handle the simple cases for put_user and
 44  * get_user without having to have .fixup sections.
 45  */
 46 
 47 struct exception_table_entry {
 48         unsigned long addr;  /* address of insn that is allowed to fault.   */
 49         int skip;            /* pcoq skip | r9 clear flag | r8 -EFAULT flag */
 50 };
 51 
 52 extern const struct exception_table_entry 
 53     *search_exception_table(unsigned long addr);
 54 
 55 #define __get_user(x,ptr)                               \
 56 ({                                                      \
 57         register long __gu_err __asm__ ("r8") = 0;      \
 58         register long __gu_val __asm__ ("r9") = 0;      \
 59                                                         \
 60         if (segment_eq(get_fs(),KERNEL_DS)) {           \
 61             switch (sizeof(*(ptr))) {                   \
 62             case 1: __get_kernel_asm("ldb",ptr); break; \
 63             case 2: __get_kernel_asm("ldh",ptr); break; \
 64             case 4: __get_kernel_asm("ldw",ptr); break; \
 65             case 8: __get_kernel_asm("ldd",ptr); break; \
 66             default: BUG(); break;                      \
 67             }                                           \
 68         }                                               \
 69         else {                                          \
 70             switch (sizeof(*(ptr))) {                   \
 71             case 1: __get_user_asm("ldb",ptr); break;   \
 72             case 2: __get_user_asm("ldh",ptr); break;   \
 73             case 4: __get_user_asm("ldw",ptr); break;   \
 74             case 8: __get_user_asm("ldd",ptr); break;   \
 75             default: BUG(); break;                      \
 76             }                                           \
 77         }                                               \
 78                                                         \
 79         (x) = (__typeof__(*(ptr))) __gu_val;            \
 80         __gu_err;                                       \
 81 })
 82 
 83 #define __get_kernel_asm(ldx,ptr)                       \
 84         __asm__("\n1:\t" ldx "\t0(%2),%0\n"             \
 85                 "2:\n"                                  \
 86                 "\t.section __ex_table,\"a\"\n"         \
 87                  "\t.word\t1b\n"                        \
 88                  "\t.word\t(2b-1b)+3\n"                 \
 89                  "\t.previous"                          \
 90                 : "=r"(__gu_val), "=r"(__gu_err)        \
 91                 : "r"(ptr), "1"(__gu_err));
 92 
 93 #define __get_user_asm(ldx,ptr)                         \
 94         __asm__("\n1:\t" ldx "\t0(%%sr3,%2),%0\n"       \
 95                 "2:\n"                                  \
 96                 "\t.section __ex_table,\"a\"\n"         \
 97                  "\t.word\t1b\n"                        \
 98                  "\t.word\t(2b-1b)+3\n"                 \
 99                  "\t.previous"                          \
100                 : "=r"(__gu_val), "=r"(__gu_err)        \
101                 : "r"(ptr), "1"(__gu_err));
102 
103 
104 #define __put_user(x,ptr)                                       \
105 ({                                                              \
106         register long __pu_err __asm__ ("r8") = 0;              \
107                                                                 \
108         if (segment_eq(get_fs(),KERNEL_DS)) {                   \
109             switch (sizeof(*(ptr))) {                           \
110             case 1: __put_kernel_asm("stb",x,ptr); break;       \
111             case 2: __put_kernel_asm("sth",x,ptr); break;       \
112             case 4: __put_kernel_asm("stw",x,ptr); break;       \
113             case 8: __put_kernel_asm("std",x,ptr); break;       \
114             default: BUG(); break;                              \
115             }                                                   \
116         }                                                       \
117         else {                                                  \
118             switch (sizeof(*(ptr))) {                           \
119             case 1: __put_user_asm("stb",x,ptr); break;         \
120             case 2: __put_user_asm("sth",x,ptr); break;         \
121             case 4: __put_user_asm("stw",x,ptr); break;         \
122             case 8: __put_user_asm("std",x,ptr); break;         \
123             default: BUG(); break;                              \
124             }                                                   \
125         }                                                       \
126                                                                 \
127         __pu_err;                                               \
128 })
129 
130 /*
131  * The "__put_user/kernel_asm()" macros tell gcc they read from memory
132  * instead of writing. This is because they do not write to any memory
133  * gcc knows about, so there are no aliasing issues.
134  */
135 
136 #define __put_kernel_asm(stx,x,ptr)                         \
137         __asm__ __volatile__ (                              \
138                 "\n1:\t" stx "\t%2,0(%1)\n"                 \
139                 "2:\n"                                      \
140                 "\t.section __ex_table,\"a\"\n"             \
141                  "\t.word\t1b\n"                            \
142                  "\t.word\t(2b-1b)+1\n"                     \
143                  "\t.previous"                              \
144                 : "=r"(__pu_err)                            \
145                 : "r"(ptr), "r"(x), ""(__pu_err))
146 
147 #define __put_user_asm(stx,x,ptr)                           \
148         __asm__ __volatile__ (                              \
149                 "\n1:\t" stx "\t%2,0(%%sr3,%1)\n"           \
150                 "2:\n"                                      \
151                 "\t.section __ex_table,\"a\"\n"             \
152                  "\t.word\t1b\n"                            \
153                  "\t.word\t(2b-1b)+1\n"                     \
154                  "\t.previous"                              \
155                 : "=r"(__pu_err)                            \
156                 : "r"(ptr), "r"(x), ""(__pu_err))
157 
158 
159 /*
160  * Complex access routines -- external declarations
161  */
162 
163 extern unsigned long lcopy_to_user(void *, const void *, unsigned long);
164 extern unsigned long lcopy_from_user(void *, const void *, unsigned long);
165 extern long lstrncpy_from_user(char *, const char *, long);
166 extern unsigned lclear_user(void *,unsigned long);
167 extern long lstrnlen_user(const char *,long);
168 
169 /*
170  * Complex access routines -- macros
171  */
172 
173 #define strncpy_from_user lstrncpy_from_user
174 #define strnlen_user lstrnlen_user
175 #define strlen_user(str) lstrnlen_user(str, 0x7fffffffL)
176 #define clear_user lclear_user
177 
178 #define copy_from_user lcopy_from_user
179 #define __copy_from_user lcopy_from_user
180 #define copy_to_user lcopy_to_user
181 #define __copy_to_user lcopy_to_user
182 
183 #define copy_to_user_ret(to,from,n,retval) \
184     ({ if (lcopy_to_user(to,from,n)) return retval; })
185 
186 #define copy_from_user_ret(to,from,n,retval) \
187     ({ if (lcopy_from_user(to,from,n)) return retval; })
188 
189 #endif /* __PARISC_UACCESS_H */
190 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.