diff options
Diffstat (limited to 'include/asm-v850/uaccess.h')
-rw-r--r-- | include/asm-v850/uaccess.h | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/include/asm-v850/uaccess.h b/include/asm-v850/uaccess.h new file mode 100644 index 000000000000..4386cfc6a8dd --- /dev/null +++ b/include/asm-v850/uaccess.h | |||
@@ -0,0 +1,165 @@ | |||
1 | #ifndef __V850_UACCESS_H__ | ||
2 | #define __V850_UACCESS_H__ | ||
3 | |||
4 | /* | ||
5 | * User space memory access functions | ||
6 | */ | ||
7 | |||
8 | #include <linux/errno.h> | ||
9 | #include <linux/string.h> | ||
10 | |||
11 | #include <asm/segment.h> | ||
12 | #include <asm/machdep.h> | ||
13 | |||
14 | #define VERIFY_READ 0 | ||
15 | #define VERIFY_WRITE 1 | ||
16 | |||
17 | extern inline int access_ok (int type, const void *addr, unsigned long size) | ||
18 | { | ||
19 | /* XXX I guess we should check against real ram bounds at least, and | ||
20 | possibly make sure ADDR is not within the kernel. | ||
21 | For now we just check to make sure it's not a small positive | ||
22 | or negative value, as that will at least catch some kinds of | ||
23 | error. In particular, we make sure that ADDR's not within the | ||
24 | interrupt vector area, which we know starts at zero, or within the | ||
25 | peripheral-I/O area, which is located just _before_ zero. */ | ||
26 | unsigned long val = (unsigned long)addr; | ||
27 | return val >= (0x80 + NUM_CPU_IRQS*16) && val < 0xFFFFF000; | ||
28 | } | ||
29 | |||
30 | /* this function will go away soon - use access_ok() instead */ | ||
31 | extern inline int __deprecated verify_area (int type, const void *addr, unsigned long size) | ||
32 | { | ||
33 | return access_ok (type, addr, size) ? 0 : -EFAULT; | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * The exception table consists of pairs of addresses: the first is the | ||
38 | * address of an instruction that is allowed to fault, and the second is | ||
39 | * the address at which the program should continue. No registers are | ||
40 | * modified, so it is entirely up to the continuation code to figure out | ||
41 | * what to do. | ||
42 | * | ||
43 | * All the routines below use bits of fixup code that are out of line | ||
44 | * with the main instruction path. This means when everything is well, | ||
45 | * we don't even have to jump over them. Further, they do not intrude | ||
46 | * on our cache or tlb entries. | ||
47 | */ | ||
48 | |||
49 | struct exception_table_entry | ||
50 | { | ||
51 | unsigned long insn, fixup; | ||
52 | }; | ||
53 | |||
54 | /* Returns 0 if exception not found and fixup otherwise. */ | ||
55 | extern unsigned long search_exception_table (unsigned long); | ||
56 | |||
57 | |||
58 | /* | ||
59 | * These are the main single-value transfer routines. They automatically | ||
60 | * use the right size if we just have the right pointer type. | ||
61 | */ | ||
62 | |||
63 | extern int bad_user_access_length (void); | ||
64 | |||
65 | #define __get_user(var, ptr) \ | ||
66 | ({ \ | ||
67 | int __gu_err = 0; \ | ||
68 | typeof(*(ptr)) __gu_val = 0; \ | ||
69 | switch (sizeof (*(ptr))) { \ | ||
70 | case 1: \ | ||
71 | case 2: \ | ||
72 | case 4: \ | ||
73 | __gu_val = *(ptr); \ | ||
74 | break; \ | ||
75 | case 8: \ | ||
76 | memcpy(&__gu_val, ptr, sizeof(__gu_val)); \ | ||
77 | break; \ | ||
78 | default: \ | ||
79 | __gu_val = 0; \ | ||
80 | __gu_err = __get_user_bad (); \ | ||
81 | break; \ | ||
82 | } \ | ||
83 | (var) = __gu_val; \ | ||
84 | __gu_err; \ | ||
85 | }) | ||
86 | #define __get_user_bad() (bad_user_access_length (), (-EFAULT)) | ||
87 | |||
88 | #define __put_user(var, ptr) \ | ||
89 | ({ \ | ||
90 | int __pu_err = 0; \ | ||
91 | switch (sizeof (*(ptr))) { \ | ||
92 | case 1: \ | ||
93 | case 2: \ | ||
94 | case 4: \ | ||
95 | *(ptr) = (var); \ | ||
96 | break; \ | ||
97 | case 8: { \ | ||
98 | typeof(*(ptr)) __pu_val = 0; \ | ||
99 | memcpy(ptr, &__pu_val, sizeof(__pu_val)); \ | ||
100 | } \ | ||
101 | break; \ | ||
102 | default: \ | ||
103 | __pu_err = __put_user_bad (); \ | ||
104 | break; \ | ||
105 | } \ | ||
106 | __pu_err; \ | ||
107 | }) | ||
108 | #define __put_user_bad() (bad_user_access_length (), (-EFAULT)) | ||
109 | |||
110 | #define put_user(x, ptr) __put_user(x, ptr) | ||
111 | #define get_user(x, ptr) __get_user(x, ptr) | ||
112 | |||
113 | #define __copy_from_user(to, from, n) (memcpy (to, from, n), 0) | ||
114 | #define __copy_to_user(to, from, n) (memcpy(to, from, n), 0) | ||
115 | |||
116 | #define __copy_to_user_inatomic __copy_to_user | ||
117 | #define __copy_from_user_inatomic __copy_from_user | ||
118 | |||
119 | #define copy_from_user(to, from, n) __copy_from_user (to, from, n) | ||
120 | #define copy_to_user(to, from, n) __copy_to_user(to, from, n) | ||
121 | |||
122 | #define copy_to_user_ret(to,from,n,retval) \ | ||
123 | ({ if (copy_to_user (to,from,n)) return retval; }) | ||
124 | |||
125 | #define copy_from_user_ret(to,from,n,retval) \ | ||
126 | ({ if (copy_from_user (to,from,n)) return retval; }) | ||
127 | |||
128 | /* | ||
129 | * Copy a null terminated string from userspace. | ||
130 | */ | ||
131 | |||
132 | static inline long | ||
133 | strncpy_from_user (char *dst, const char *src, long count) | ||
134 | { | ||
135 | char *tmp; | ||
136 | strncpy (dst, src, count); | ||
137 | for (tmp = dst; *tmp && count > 0; tmp++, count--) | ||
138 | ; | ||
139 | return tmp - dst; | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * Return the size of a string (including the ending 0) | ||
144 | * | ||
145 | * Return 0 on exception, a value greater than N if too long | ||
146 | */ | ||
147 | static inline long strnlen_user (const char *src, long n) | ||
148 | { | ||
149 | return strlen (src) + 1; | ||
150 | } | ||
151 | |||
152 | #define strlen_user(str) strnlen_user (str, 32767) | ||
153 | |||
154 | /* | ||
155 | * Zero Userspace | ||
156 | */ | ||
157 | |||
158 | static inline unsigned long | ||
159 | clear_user (void *to, unsigned long n) | ||
160 | { | ||
161 | memset (to, 0, n); | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | #endif /* __V850_UACCESS_H__ */ | ||