aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc64/kernel/sys32.S145
-rw-r--r--arch/sparc64/kernel/traps.c24
-rw-r--r--arch/sparc64/kernel/unaligned.c9
-rw-r--r--arch/sparc64/mm/Makefile2
-rw-r--r--arch/sparc64/mm/extable.c80
-rw-r--r--arch/sparc64/mm/fault.c10
-rw-r--r--include/asm-sparc64/uaccess.h17
7 files changed, 101 insertions, 186 deletions
diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S
index 5f9e4fae612e..4fb99e0bc7c3 100644
--- a/arch/sparc64/kernel/sys32.S
+++ b/arch/sparc64/kernel/sys32.S
@@ -158,163 +158,163 @@ sys32_socketcall: /* %o0=call, %o1=args */
158 jmpl %g2 + %o0, %g0 158 jmpl %g2 + %o0, %g0
159 nop 159 nop
160 160
161 /* Each entry is exactly 32 bytes. */
162 .align 32 161 .align 32
163__socketcall_table_begin: 162__socketcall_table_begin:
163
164 /* Each entry is exactly 32 bytes. */
164do_sys_socket: /* sys_socket(int, int, int) */ 165do_sys_socket: /* sys_socket(int, int, int) */
165 ldswa [%o1 + 0x0] %asi, %o0 1661: ldswa [%o1 + 0x0] %asi, %o0
166 sethi %hi(sys_socket), %g1 167 sethi %hi(sys_socket), %g1
167 ldswa [%o1 + 0x8] %asi, %o2 1682: ldswa [%o1 + 0x8] %asi, %o2
168 jmpl %g1 + %lo(sys_socket), %g0 169 jmpl %g1 + %lo(sys_socket), %g0
169 ldswa [%o1 + 0x4] %asi, %o1 1703: ldswa [%o1 + 0x4] %asi, %o1
170 nop 171 nop
171 nop 172 nop
172 nop 173 nop
173do_sys_bind: /* sys_bind(int fd, struct sockaddr *, int) */ 174do_sys_bind: /* sys_bind(int fd, struct sockaddr *, int) */
174 ldswa [%o1 + 0x0] %asi, %o0 1754: ldswa [%o1 + 0x0] %asi, %o0
175 sethi %hi(sys_bind), %g1 176 sethi %hi(sys_bind), %g1
176 ldswa [%o1 + 0x8] %asi, %o2 1775: ldswa [%o1 + 0x8] %asi, %o2
177 jmpl %g1 + %lo(sys_bind), %g0 178 jmpl %g1 + %lo(sys_bind), %g0
178 lduwa [%o1 + 0x4] %asi, %o1 1796: lduwa [%o1 + 0x4] %asi, %o1
179 nop 180 nop
180 nop 181 nop
181 nop 182 nop
182do_sys_connect: /* sys_connect(int, struct sockaddr *, int) */ 183do_sys_connect: /* sys_connect(int, struct sockaddr *, int) */
183 ldswa [%o1 + 0x0] %asi, %o0 1847: ldswa [%o1 + 0x0] %asi, %o0
184 sethi %hi(sys_connect), %g1 185 sethi %hi(sys_connect), %g1
185 ldswa [%o1 + 0x8] %asi, %o2 1868: ldswa [%o1 + 0x8] %asi, %o2
186 jmpl %g1 + %lo(sys_connect), %g0 187 jmpl %g1 + %lo(sys_connect), %g0
187 lduwa [%o1 + 0x4] %asi, %o1 1889: lduwa [%o1 + 0x4] %asi, %o1
188 nop 189 nop
189 nop 190 nop
190 nop 191 nop
191do_sys_listen: /* sys_listen(int, int) */ 192do_sys_listen: /* sys_listen(int, int) */
192 ldswa [%o1 + 0x0] %asi, %o0 19310: ldswa [%o1 + 0x0] %asi, %o0
193 sethi %hi(sys_listen), %g1 194 sethi %hi(sys_listen), %g1
194 jmpl %g1 + %lo(sys_listen), %g0 195 jmpl %g1 + %lo(sys_listen), %g0
195 ldswa [%o1 + 0x4] %asi, %o1 19611: ldswa [%o1 + 0x4] %asi, %o1
196 nop 197 nop
197 nop 198 nop
198 nop 199 nop
199 nop 200 nop
200do_sys_accept: /* sys_accept(int, struct sockaddr *, int *) */ 201do_sys_accept: /* sys_accept(int, struct sockaddr *, int *) */
201 ldswa [%o1 + 0x0] %asi, %o0 20212: ldswa [%o1 + 0x0] %asi, %o0
202 sethi %hi(sys_accept), %g1 203 sethi %hi(sys_accept), %g1
203 lduwa [%o1 + 0x8] %asi, %o2 20413: lduwa [%o1 + 0x8] %asi, %o2
204 jmpl %g1 + %lo(sys_accept), %g0 205 jmpl %g1 + %lo(sys_accept), %g0
205 lduwa [%o1 + 0x4] %asi, %o1 20614: lduwa [%o1 + 0x4] %asi, %o1
206 nop 207 nop
207 nop 208 nop
208 nop 209 nop
209do_sys_getsockname: /* sys_getsockname(int, struct sockaddr *, int *) */ 210do_sys_getsockname: /* sys_getsockname(int, struct sockaddr *, int *) */
210 ldswa [%o1 + 0x0] %asi, %o0 21115: ldswa [%o1 + 0x0] %asi, %o0
211 sethi %hi(sys_getsockname), %g1 212 sethi %hi(sys_getsockname), %g1
212 lduwa [%o1 + 0x8] %asi, %o2 21316: lduwa [%o1 + 0x8] %asi, %o2
213 jmpl %g1 + %lo(sys_getsockname), %g0 214 jmpl %g1 + %lo(sys_getsockname), %g0
214 lduwa [%o1 + 0x4] %asi, %o1 21517: lduwa [%o1 + 0x4] %asi, %o1
215 nop 216 nop
216 nop 217 nop
217 nop 218 nop
218do_sys_getpeername: /* sys_getpeername(int, struct sockaddr *, int *) */ 219do_sys_getpeername: /* sys_getpeername(int, struct sockaddr *, int *) */
219 ldswa [%o1 + 0x0] %asi, %o0 22018: ldswa [%o1 + 0x0] %asi, %o0
220 sethi %hi(sys_getpeername), %g1 221 sethi %hi(sys_getpeername), %g1
221 lduwa [%o1 + 0x8] %asi, %o2 22219: lduwa [%o1 + 0x8] %asi, %o2
222 jmpl %g1 + %lo(sys_getpeername), %g0 223 jmpl %g1 + %lo(sys_getpeername), %g0
223 lduwa [%o1 + 0x4] %asi, %o1 22420: lduwa [%o1 + 0x4] %asi, %o1
224 nop 225 nop
225 nop 226 nop
226 nop 227 nop
227do_sys_socketpair: /* sys_socketpair(int, int, int, int *) */ 228do_sys_socketpair: /* sys_socketpair(int, int, int, int *) */
228 ldswa [%o1 + 0x0] %asi, %o0 22921: ldswa [%o1 + 0x0] %asi, %o0
229 sethi %hi(sys_socketpair), %g1 230 sethi %hi(sys_socketpair), %g1
230 ldswa [%o1 + 0x8] %asi, %o2 23122: ldswa [%o1 + 0x8] %asi, %o2
231 lduwa [%o1 + 0xc] %asi, %o3 23223: lduwa [%o1 + 0xc] %asi, %o3
232 jmpl %g1 + %lo(sys_socketpair), %g0 233 jmpl %g1 + %lo(sys_socketpair), %g0
233 ldswa [%o1 + 0x4] %asi, %o1 23424: ldswa [%o1 + 0x4] %asi, %o1
234 nop 235 nop
235 nop 236 nop
236do_sys_send: /* sys_send(int, void *, size_t, unsigned int) */ 237do_sys_send: /* sys_send(int, void *, size_t, unsigned int) */
237 ldswa [%o1 + 0x0] %asi, %o0 23825: ldswa [%o1 + 0x0] %asi, %o0
238 sethi %hi(sys_send), %g1 239 sethi %hi(sys_send), %g1
239 lduwa [%o1 + 0x8] %asi, %o2 24026: lduwa [%o1 + 0x8] %asi, %o2
240 lduwa [%o1 + 0xc] %asi, %o3 24127: lduwa [%o1 + 0xc] %asi, %o3
241 jmpl %g1 + %lo(sys_send), %g0 242 jmpl %g1 + %lo(sys_send), %g0
242 lduwa [%o1 + 0x4] %asi, %o1 24328: lduwa [%o1 + 0x4] %asi, %o1
243 nop 244 nop
244 nop 245 nop
245do_sys_recv: /* sys_recv(int, void *, size_t, unsigned int) */ 246do_sys_recv: /* sys_recv(int, void *, size_t, unsigned int) */
246 ldswa [%o1 + 0x0] %asi, %o0 24729: ldswa [%o1 + 0x0] %asi, %o0
247 sethi %hi(sys_recv), %g1 248 sethi %hi(sys_recv), %g1
248 lduwa [%o1 + 0x8] %asi, %o2 24930: lduwa [%o1 + 0x8] %asi, %o2
249 lduwa [%o1 + 0xc] %asi, %o3 25031: lduwa [%o1 + 0xc] %asi, %o3
250 jmpl %g1 + %lo(sys_recv), %g0 251 jmpl %g1 + %lo(sys_recv), %g0
251 lduwa [%o1 + 0x4] %asi, %o1 25232: lduwa [%o1 + 0x4] %asi, %o1
252 nop 253 nop
253 nop 254 nop
254do_sys_sendto: /* sys_sendto(int, u32, compat_size_t, unsigned int, u32, int) */ 255do_sys_sendto: /* sys_sendto(int, u32, compat_size_t, unsigned int, u32, int) */
255 ldswa [%o1 + 0x0] %asi, %o0 25633: ldswa [%o1 + 0x0] %asi, %o0
256 sethi %hi(sys_sendto), %g1 257 sethi %hi(sys_sendto), %g1
257 lduwa [%o1 + 0x8] %asi, %o2 25834: lduwa [%o1 + 0x8] %asi, %o2
258 lduwa [%o1 + 0xc] %asi, %o3 25935: lduwa [%o1 + 0xc] %asi, %o3
259 lduwa [%o1 + 0x10] %asi, %o4 26036: lduwa [%o1 + 0x10] %asi, %o4
260 ldswa [%o1 + 0x14] %asi, %o5 26137: ldswa [%o1 + 0x14] %asi, %o5
261 jmpl %g1 + %lo(sys_sendto), %g0 262 jmpl %g1 + %lo(sys_sendto), %g0
262 lduwa [%o1 + 0x4] %asi, %o1 26338: lduwa [%o1 + 0x4] %asi, %o1
263do_sys_recvfrom: /* sys_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */ 264do_sys_recvfrom: /* sys_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */
264 ldswa [%o1 + 0x0] %asi, %o0 26539: ldswa [%o1 + 0x0] %asi, %o0
265 sethi %hi(sys_recvfrom), %g1 266 sethi %hi(sys_recvfrom), %g1
266 lduwa [%o1 + 0x8] %asi, %o2 26740: lduwa [%o1 + 0x8] %asi, %o2
267 lduwa [%o1 + 0xc] %asi, %o3 26841: lduwa [%o1 + 0xc] %asi, %o3
268 lduwa [%o1 + 0x10] %asi, %o4 26942: lduwa [%o1 + 0x10] %asi, %o4
269 lduwa [%o1 + 0x14] %asi, %o5 27043: lduwa [%o1 + 0x14] %asi, %o5
270 jmpl %g1 + %lo(sys_recvfrom), %g0 271 jmpl %g1 + %lo(sys_recvfrom), %g0
271 lduwa [%o1 + 0x4] %asi, %o1 27244: lduwa [%o1 + 0x4] %asi, %o1
272do_sys_shutdown: /* sys_shutdown(int, int) */ 273do_sys_shutdown: /* sys_shutdown(int, int) */
273 ldswa [%o1 + 0x0] %asi, %o0 27445: ldswa [%o1 + 0x0] %asi, %o0
274 sethi %hi(sys_shutdown), %g1 275 sethi %hi(sys_shutdown), %g1
275 jmpl %g1 + %lo(sys_shutdown), %g0 276 jmpl %g1 + %lo(sys_shutdown), %g0
276 ldswa [%o1 + 0x4] %asi, %o1 27746: ldswa [%o1 + 0x4] %asi, %o1
277 nop 278 nop
278 nop 279 nop
279 nop 280 nop
280 nop 281 nop
281do_sys_setsockopt: /* compat_sys_setsockopt(int, int, int, char *, int) */ 282do_sys_setsockopt: /* compat_sys_setsockopt(int, int, int, char *, int) */
282 ldswa [%o1 + 0x0] %asi, %o0 28347: ldswa [%o1 + 0x0] %asi, %o0
283 sethi %hi(compat_sys_setsockopt), %g1 284 sethi %hi(compat_sys_setsockopt), %g1
284 ldswa [%o1 + 0x8] %asi, %o2 28548: ldswa [%o1 + 0x8] %asi, %o2
285 lduwa [%o1 + 0xc] %asi, %o3 28649: lduwa [%o1 + 0xc] %asi, %o3
286 ldswa [%o1 + 0x10] %asi, %o4 28750: ldswa [%o1 + 0x10] %asi, %o4
287 jmpl %g1 + %lo(compat_sys_setsockopt), %g0 288 jmpl %g1 + %lo(compat_sys_setsockopt), %g0
288 ldswa [%o1 + 0x4] %asi, %o1 28951: ldswa [%o1 + 0x4] %asi, %o1
289 nop 290 nop
290do_sys_getsockopt: /* compat_sys_getsockopt(int, int, int, u32, u32) */ 291do_sys_getsockopt: /* compat_sys_getsockopt(int, int, int, u32, u32) */
291 ldswa [%o1 + 0x0] %asi, %o0 29252: ldswa [%o1 + 0x0] %asi, %o0
292 sethi %hi(compat_sys_getsockopt), %g1 293 sethi %hi(compat_sys_getsockopt), %g1
293 ldswa [%o1 + 0x8] %asi, %o2 29453: ldswa [%o1 + 0x8] %asi, %o2
294 lduwa [%o1 + 0xc] %asi, %o3 29554: lduwa [%o1 + 0xc] %asi, %o3
295 lduwa [%o1 + 0x10] %asi, %o4 29655: lduwa [%o1 + 0x10] %asi, %o4
296 jmpl %g1 + %lo(compat_sys_getsockopt), %g0 297 jmpl %g1 + %lo(compat_sys_getsockopt), %g0
297 ldswa [%o1 + 0x4] %asi, %o1 29856: ldswa [%o1 + 0x4] %asi, %o1
298 nop 299 nop
299do_sys_sendmsg: /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */ 300do_sys_sendmsg: /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */
300 ldswa [%o1 + 0x0] %asi, %o0 30157: ldswa [%o1 + 0x0] %asi, %o0
301 sethi %hi(compat_sys_sendmsg), %g1 302 sethi %hi(compat_sys_sendmsg), %g1
302 lduwa [%o1 + 0x8] %asi, %o2 30358: lduwa [%o1 + 0x8] %asi, %o2
303 jmpl %g1 + %lo(compat_sys_sendmsg), %g0 304 jmpl %g1 + %lo(compat_sys_sendmsg), %g0
304 lduwa [%o1 + 0x4] %asi, %o1 30559: lduwa [%o1 + 0x4] %asi, %o1
305 nop 306 nop
306 nop 307 nop
307 nop 308 nop
308do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) */ 309do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) */
309 ldswa [%o1 + 0x0] %asi, %o0 31060: ldswa [%o1 + 0x0] %asi, %o0
310 sethi %hi(compat_sys_recvmsg), %g1 311 sethi %hi(compat_sys_recvmsg), %g1
311 lduwa [%o1 + 0x8] %asi, %o2 31261: lduwa [%o1 + 0x8] %asi, %o2
312 jmpl %g1 + %lo(compat_sys_recvmsg), %g0 313 jmpl %g1 + %lo(compat_sys_recvmsg), %g0
313 lduwa [%o1 + 0x4] %asi, %o1 31462: lduwa [%o1 + 0x4] %asi, %o1
314 nop 315 nop
315 nop 316 nop
316 nop 317 nop
317__socketcall_table_end:
318 318
319do_einval: 319do_einval:
320 retl 320 retl
@@ -325,5 +325,20 @@ do_efault:
325 325
326 .section __ex_table 326 .section __ex_table
327 .align 4 327 .align 4
328 .word __socketcall_table_begin, 0, __socketcall_table_end, do_efault 328 .word 1b, do_efault, 2b, do_efault, 3b, do_efault, 4b, do_efault
329 .word 5b, do_efault, 6b, do_efault, 7b, do_efault, 8b, do_efault
330 .word 9b, do_efault, 10b, do_efault, 11b, do_efault, 12b, do_efault
331 .word 13b, do_efault, 14b, do_efault, 15b, do_efault, 16b, do_efault
332 .word 17b, do_efault, 18b, do_efault, 19b, do_efault, 20b, do_efault
333 .word 21b, do_efault, 22b, do_efault, 23b, do_efault, 24b, do_efault
334 .word 25b, do_efault, 26b, do_efault, 27b, do_efault, 28b, do_efault
335 .word 29b, do_efault, 30b, do_efault, 31b, do_efault, 32b, do_efault
336 .word 33b, do_efault, 34b, do_efault, 35b, do_efault, 36b, do_efault
337 .word 37b, do_efault, 38b, do_efault, 39b, do_efault, 40b, do_efault
338 .word 41b, do_efault, 42b, do_efault, 43b, do_efault, 44b, do_efault
339 .word 45b, do_efault, 46b, do_efault, 47b, do_efault, 48b, do_efault
340 .word 49b, do_efault, 50b, do_efault, 51b, do_efault, 52b, do_efault
341 .word 53b, do_efault, 54b, do_efault, 55b, do_efault, 56b, do_efault
342 .word 57b, do_efault, 58b, do_efault, 59b, do_efault, 60b, do_efault
343 .word 61b, do_efault, 62b, do_efault
329 .previous 344 .previous
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index f8e7005fede9..1aa15990f5af 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -189,19 +189,18 @@ void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, un
189 189
190 if (regs->tstate & TSTATE_PRIV) { 190 if (regs->tstate & TSTATE_PRIV) {
191 /* Test if this comes from uaccess places. */ 191 /* Test if this comes from uaccess places. */
192 unsigned long fixup; 192 const struct exception_table_entry *entry;
193 unsigned long g2 = regs->u_regs[UREG_G2];
194 193
195 if ((fixup = search_extables_range(regs->tpc, &g2))) { 194 entry = search_exception_tables(regs->tpc);
196 /* Ouch, somebody is trying ugly VM hole tricks on us... */ 195 if (entry) {
196 /* Ouch, somebody is trying VM hole tricks on us... */
197#ifdef DEBUG_EXCEPTIONS 197#ifdef DEBUG_EXCEPTIONS
198 printk("Exception: PC<%016lx> faddr<UNKNOWN>\n", regs->tpc); 198 printk("Exception: PC<%016lx> faddr<UNKNOWN>\n", regs->tpc);
199 printk("EX_TABLE: insn<%016lx> fixup<%016lx> " 199 printk("EX_TABLE: insn<%016lx> fixup<%016lx>\n",
200 "g2<%016lx>\n", regs->tpc, fixup, g2); 200 regs->tpc, entry->fixup);
201#endif 201#endif
202 regs->tpc = fixup; 202 regs->tpc = entry->fixup;
203 regs->tnpc = regs->tpc + 4; 203 regs->tnpc = regs->tpc + 4;
204 regs->u_regs[UREG_G2] = g2;
205 return; 204 return;
206 } 205 }
207 /* Shit... */ 206 /* Shit... */
@@ -1610,10 +1609,10 @@ void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned
1610 /* OK, usermode access. */ 1609 /* OK, usermode access. */
1611 recoverable = 1; 1610 recoverable = 1;
1612 } else { 1611 } else {
1613 unsigned long g2 = regs->u_regs[UREG_G2]; 1612 const struct exception_table_entry *entry;
1614 unsigned long fixup = search_extables_range(regs->tpc, &g2);
1615 1613
1616 if (fixup != 0UL) { 1614 entry = search_exception_tables(regs->tpc);
1615 if (entry) {
1617 /* OK, kernel access to userspace. */ 1616 /* OK, kernel access to userspace. */
1618 recoverable = 1; 1617 recoverable = 1;
1619 1618
@@ -1632,9 +1631,8 @@ void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned
1632 * recoverable condition. 1631 * recoverable condition.
1633 */ 1632 */
1634 if (recoverable) { 1633 if (recoverable) {
1635 regs->tpc = fixup; 1634 regs->tpc = entry->fixup;
1636 regs->tnpc = regs->tpc + 4; 1635 regs->tnpc = regs->tpc + 4;
1637 regs->u_regs[UREG_G2] = g2;
1638 } 1636 }
1639 } 1637 }
1640 } 1638 }
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
index 02af08ffec8f..9d6be20f4125 100644
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -246,10 +246,10 @@ void kernel_mna_trap_fault(void)
246{ 246{
247 struct pt_regs *regs = current_thread_info()->kern_una_regs; 247 struct pt_regs *regs = current_thread_info()->kern_una_regs;
248 unsigned int insn = current_thread_info()->kern_una_insn; 248 unsigned int insn = current_thread_info()->kern_una_insn;
249 unsigned long g2 = regs->u_regs[UREG_G2]; 249 const struct exception_table_entry *entry;
250 unsigned long fixup = search_extables_range(regs->tpc, &g2);
251 250
252 if (!fixup) { 251 entry = search_exception_tables(regs->tpc);
252 if (!entry) {
253 unsigned long address; 253 unsigned long address;
254 254
255 address = compute_effective_address(regs, insn, 255 address = compute_effective_address(regs, insn,
@@ -270,9 +270,8 @@ void kernel_mna_trap_fault(void)
270 die_if_kernel("Oops", regs); 270 die_if_kernel("Oops", regs);
271 /* Not reached */ 271 /* Not reached */
272 } 272 }
273 regs->tpc = fixup; 273 regs->tpc = entry->fixup;
274 regs->tnpc = regs->tpc + 4; 274 regs->tnpc = regs->tpc + 4;
275 regs->u_regs [UREG_G2] = g2;
276 275
277 regs->tstate &= ~TSTATE_ASI; 276 regs->tstate &= ~TSTATE_ASI;
278 regs->tstate |= (ASI_AIUS << 24UL); 277 regs->tstate |= (ASI_AIUS << 24UL);
diff --git a/arch/sparc64/mm/Makefile b/arch/sparc64/mm/Makefile
index cda87333a77b..9d0960e69f48 100644
--- a/arch/sparc64/mm/Makefile
+++ b/arch/sparc64/mm/Makefile
@@ -5,6 +5,6 @@
5EXTRA_AFLAGS := -ansi 5EXTRA_AFLAGS := -ansi
6EXTRA_CFLAGS := -Werror 6EXTRA_CFLAGS := -Werror
7 7
8obj-y := ultra.o tlb.o fault.o init.o generic.o extable.o 8obj-y := ultra.o tlb.o fault.o init.o generic.o
9 9
10obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 10obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff --git a/arch/sparc64/mm/extable.c b/arch/sparc64/mm/extable.c
deleted file mode 100644
index ec334297ff4f..000000000000
--- a/arch/sparc64/mm/extable.c
+++ /dev/null
@@ -1,80 +0,0 @@
1/*
2 * linux/arch/sparc64/mm/extable.c
3 */
4
5#include <linux/config.h>
6#include <linux/module.h>
7#include <asm/uaccess.h>
8
9extern const struct exception_table_entry __start___ex_table[];
10extern const struct exception_table_entry __stop___ex_table[];
11
12void sort_extable(struct exception_table_entry *start,
13 struct exception_table_entry *finish)
14{
15}
16
17/* Caller knows they are in a range if ret->fixup == 0 */
18const struct exception_table_entry *
19search_extable(const struct exception_table_entry *start,
20 const struct exception_table_entry *last,
21 unsigned long value)
22{
23 const struct exception_table_entry *walk;
24
25 /* Single insn entries are encoded as:
26 * word 1: insn address
27 * word 2: fixup code address
28 *
29 * Range entries are encoded as:
30 * word 1: first insn address
31 * word 2: 0
32 * word 3: last insn address + 4 bytes
33 * word 4: fixup code address
34 *
35 * See asm/uaccess.h for more details.
36 */
37
38 /* 1. Try to find an exact match. */
39 for (walk = start; walk <= last; walk++) {
40 if (walk->fixup == 0) {
41 /* A range entry, skip both parts. */
42 walk++;
43 continue;
44 }
45
46 if (walk->insn == value)
47 return walk;
48 }
49
50 /* 2. Try to find a range match. */
51 for (walk = start; walk <= (last - 1); walk++) {
52 if (walk->fixup)
53 continue;
54
55 if (walk[0].insn <= value && walk[1].insn > value)
56 return walk;
57
58 walk++;
59 }
60
61 return NULL;
62}
63
64/* Special extable search, which handles ranges. Returns fixup */
65unsigned long search_extables_range(unsigned long addr, unsigned long *g2)
66{
67 const struct exception_table_entry *entry;
68
69 entry = search_exception_tables(addr);
70 if (!entry)
71 return 0;
72
73 /* Inside range? Fix g2 and return correct fixup */
74 if (!entry->fixup) {
75 *g2 = (addr - entry->insn) / 4;
76 return (entry + 1)->fixup;
77 }
78
79 return entry->fixup;
80}
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index db1e3310e907..59dc9a2ece5a 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -242,7 +242,6 @@ static unsigned int get_fault_insn(struct pt_regs *regs, unsigned int insn)
242static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, 242static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
243 unsigned int insn, unsigned long address) 243 unsigned int insn, unsigned long address)
244{ 244{
245 unsigned long g2;
246 unsigned char asi = ASI_P; 245 unsigned char asi = ASI_P;
247 246
248 if ((!insn) && (regs->tstate & TSTATE_PRIV)) 247 if ((!insn) && (regs->tstate & TSTATE_PRIV))
@@ -273,11 +272,9 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
273 } 272 }
274 } 273 }
275 274
276 g2 = regs->u_regs[UREG_G2];
277
278 /* Is this in ex_table? */ 275 /* Is this in ex_table? */
279 if (regs->tstate & TSTATE_PRIV) { 276 if (regs->tstate & TSTATE_PRIV) {
280 unsigned long fixup; 277 const struct exception_table_entry *entry;
281 278
282 if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) { 279 if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) {
283 if (insn & 0x2000) 280 if (insn & 0x2000)
@@ -288,10 +285,9 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
288 285
289 /* Look in asi.h: All _S asis have LS bit set */ 286 /* Look in asi.h: All _S asis have LS bit set */
290 if ((asi & 0x1) && 287 if ((asi & 0x1) &&
291 (fixup = search_extables_range(regs->tpc, &g2))) { 288 (entry = search_exception_tables(regs->tpc))) {
292 regs->tpc = fixup; 289 regs->tpc = entry->fixup;
293 regs->tnpc = regs->tpc + 4; 290 regs->tnpc = regs->tpc + 4;
294 regs->u_regs[UREG_G2] = g2;
295 return; 291 return;
296 } 292 }
297 } else { 293 } else {
diff --git a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h
index 80a65d7e3dbf..c099aa339784 100644
--- a/include/asm-sparc64/uaccess.h
+++ b/include/asm-sparc64/uaccess.h
@@ -70,25 +70,12 @@ static inline int access_ok(int type, const void __user * addr, unsigned long si
70 * with the main instruction path. This means when everything is well, 70 * with the main instruction path. This means when everything is well,
71 * we don't even have to jump over them. Further, they do not intrude 71 * we don't even have to jump over them. Further, they do not intrude
72 * on our cache or tlb entries. 72 * on our cache or tlb entries.
73 *
74 * There is a special way how to put a range of potentially faulting
75 * insns (like twenty ldd/std's with now intervening other instructions)
76 * You specify address of first in insn and 0 in fixup and in the next
77 * exception_table_entry you specify last potentially faulting insn + 1
78 * and in fixup the routine which should handle the fault.
79 * That fixup code will get
80 * (faulting_insn_address - first_insn_in_the_range_address)/4
81 * in %g2 (ie. index of the faulting instruction in the range).
82 */ 73 */
83 74
84struct exception_table_entry 75struct exception_table_entry {
85{ 76 unsigned int insn, fixup;
86 unsigned insn, fixup;
87}; 77};
88 78
89/* Special exable search, which handles ranges. Returns fixup */
90unsigned long search_extables_range(unsigned long addr, unsigned long *g2);
91
92extern void __ret_efault(void); 79extern void __ret_efault(void);
93 80
94/* Uh, these should become the main single-value transfer routines.. 81/* Uh, these should become the main single-value transfer routines..