diff options
Diffstat (limited to 'arch/arm/include/asm/uaccess.h')
-rw-r--r-- | arch/arm/include/asm/uaccess.h | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index a4cd7af475e9..4767eb9caa78 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h | |||
@@ -107,8 +107,11 @@ static inline void set_fs(mm_segment_t fs) | |||
107 | extern int __get_user_1(void *); | 107 | extern int __get_user_1(void *); |
108 | extern int __get_user_2(void *); | 108 | extern int __get_user_2(void *); |
109 | extern int __get_user_4(void *); | 109 | extern int __get_user_4(void *); |
110 | extern int __get_user_lo8(void *); | 110 | extern int __get_user_32t_8(void *); |
111 | extern int __get_user_8(void *); | 111 | extern int __get_user_8(void *); |
112 | extern int __get_user_64t_1(void *); | ||
113 | extern int __get_user_64t_2(void *); | ||
114 | extern int __get_user_64t_4(void *); | ||
112 | 115 | ||
113 | #define __GUP_CLOBBER_1 "lr", "cc" | 116 | #define __GUP_CLOBBER_1 "lr", "cc" |
114 | #ifdef CONFIG_CPU_USE_DOMAINS | 117 | #ifdef CONFIG_CPU_USE_DOMAINS |
@@ -117,7 +120,7 @@ extern int __get_user_8(void *); | |||
117 | #define __GUP_CLOBBER_2 "lr", "cc" | 120 | #define __GUP_CLOBBER_2 "lr", "cc" |
118 | #endif | 121 | #endif |
119 | #define __GUP_CLOBBER_4 "lr", "cc" | 122 | #define __GUP_CLOBBER_4 "lr", "cc" |
120 | #define __GUP_CLOBBER_lo8 "lr", "cc" | 123 | #define __GUP_CLOBBER_32t_8 "lr", "cc" |
121 | #define __GUP_CLOBBER_8 "lr", "cc" | 124 | #define __GUP_CLOBBER_8 "lr", "cc" |
122 | 125 | ||
123 | #define __get_user_x(__r2,__p,__e,__l,__s) \ | 126 | #define __get_user_x(__r2,__p,__e,__l,__s) \ |
@@ -131,12 +134,30 @@ extern int __get_user_8(void *); | |||
131 | 134 | ||
132 | /* narrowing a double-word get into a single 32bit word register: */ | 135 | /* narrowing a double-word get into a single 32bit word register: */ |
133 | #ifdef __ARMEB__ | 136 | #ifdef __ARMEB__ |
134 | #define __get_user_xb(__r2, __p, __e, __l, __s) \ | 137 | #define __get_user_x_32t(__r2, __p, __e, __l, __s) \ |
135 | __get_user_x(__r2, __p, __e, __l, lo8) | 138 | __get_user_x(__r2, __p, __e, __l, 32t_8) |
136 | #else | 139 | #else |
137 | #define __get_user_xb __get_user_x | 140 | #define __get_user_x_32t __get_user_x |
138 | #endif | 141 | #endif |
139 | 142 | ||
143 | /* | ||
144 | * storing result into proper least significant word of 64bit target var, | ||
145 | * different only for big endian case where 64 bit __r2 lsw is r3: | ||
146 | */ | ||
147 | #ifdef __ARMEB__ | ||
148 | #define __get_user_x_64t(__r2, __p, __e, __l, __s) \ | ||
149 | __asm__ __volatile__ ( \ | ||
150 | __asmeq("%0", "r0") __asmeq("%1", "r2") \ | ||
151 | __asmeq("%3", "r1") \ | ||
152 | "bl __get_user_64t_" #__s \ | ||
153 | : "=&r" (__e), "=r" (__r2) \ | ||
154 | : "0" (__p), "r" (__l) \ | ||
155 | : __GUP_CLOBBER_##__s) | ||
156 | #else | ||
157 | #define __get_user_x_64t __get_user_x | ||
158 | #endif | ||
159 | |||
160 | |||
140 | #define __get_user_check(x,p) \ | 161 | #define __get_user_check(x,p) \ |
141 | ({ \ | 162 | ({ \ |
142 | unsigned long __limit = current_thread_info()->addr_limit - 1; \ | 163 | unsigned long __limit = current_thread_info()->addr_limit - 1; \ |
@@ -146,17 +167,26 @@ extern int __get_user_8(void *); | |||
146 | register int __e asm("r0"); \ | 167 | register int __e asm("r0"); \ |
147 | switch (sizeof(*(__p))) { \ | 168 | switch (sizeof(*(__p))) { \ |
148 | case 1: \ | 169 | case 1: \ |
149 | __get_user_x(__r2, __p, __e, __l, 1); \ | 170 | if (sizeof((x)) >= 8) \ |
171 | __get_user_x_64t(__r2, __p, __e, __l, 1); \ | ||
172 | else \ | ||
173 | __get_user_x(__r2, __p, __e, __l, 1); \ | ||
150 | break; \ | 174 | break; \ |
151 | case 2: \ | 175 | case 2: \ |
152 | __get_user_x(__r2, __p, __e, __l, 2); \ | 176 | if (sizeof((x)) >= 8) \ |
177 | __get_user_x_64t(__r2, __p, __e, __l, 2); \ | ||
178 | else \ | ||
179 | __get_user_x(__r2, __p, __e, __l, 2); \ | ||
153 | break; \ | 180 | break; \ |
154 | case 4: \ | 181 | case 4: \ |
155 | __get_user_x(__r2, __p, __e, __l, 4); \ | 182 | if (sizeof((x)) >= 8) \ |
183 | __get_user_x_64t(__r2, __p, __e, __l, 4); \ | ||
184 | else \ | ||
185 | __get_user_x(__r2, __p, __e, __l, 4); \ | ||
156 | break; \ | 186 | break; \ |
157 | case 8: \ | 187 | case 8: \ |
158 | if (sizeof((x)) < 8) \ | 188 | if (sizeof((x)) < 8) \ |
159 | __get_user_xb(__r2, __p, __e, __l, 4); \ | 189 | __get_user_x_32t(__r2, __p, __e, __l, 4); \ |
160 | else \ | 190 | else \ |
161 | __get_user_x(__r2, __p, __e, __l, 8); \ | 191 | __get_user_x(__r2, __p, __e, __l, 8); \ |
162 | break; \ | 192 | break; \ |