diff options
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/calls.S | 8 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 17 | ||||
-rw-r--r-- | arch/arm/kernel/sys_oabi-compat.c | 71 |
3 files changed, 91 insertions, 5 deletions
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index d058e7c12568..8c3035d5ffc9 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
@@ -291,21 +291,21 @@ | |||
291 | CALL(sys_mq_getsetattr) | 291 | CALL(sys_mq_getsetattr) |
292 | /* 280 */ CALL(sys_waitid) | 292 | /* 280 */ CALL(sys_waitid) |
293 | CALL(sys_socket) | 293 | CALL(sys_socket) |
294 | CALL(sys_bind) | 294 | CALL(ABI(sys_bind, sys_oabi_bind)) |
295 | CALL(sys_connect) | 295 | CALL(ABI(sys_connect, sys_oabi_connect)) |
296 | CALL(sys_listen) | 296 | CALL(sys_listen) |
297 | /* 285 */ CALL(sys_accept) | 297 | /* 285 */ CALL(sys_accept) |
298 | CALL(sys_getsockname) | 298 | CALL(sys_getsockname) |
299 | CALL(sys_getpeername) | 299 | CALL(sys_getpeername) |
300 | CALL(sys_socketpair) | 300 | CALL(sys_socketpair) |
301 | CALL(sys_send) | 301 | CALL(sys_send) |
302 | /* 290 */ CALL(sys_sendto) | 302 | /* 290 */ CALL(ABI(sys_sendto, sys_oabi_sendto)) |
303 | CALL(sys_recv) | 303 | CALL(sys_recv) |
304 | CALL(sys_recvfrom) | 304 | CALL(sys_recvfrom) |
305 | CALL(sys_shutdown) | 305 | CALL(sys_shutdown) |
306 | CALL(sys_setsockopt) | 306 | CALL(sys_setsockopt) |
307 | /* 295 */ CALL(sys_getsockopt) | 307 | /* 295 */ CALL(sys_getsockopt) |
308 | CALL(sys_sendmsg) | 308 | CALL(ABI(sys_sendmsg, sys_oabi_sendmsg)) |
309 | CALL(sys_recvmsg) | 309 | CALL(sys_recvmsg) |
310 | CALL(ABI(sys_semop, sys_oabi_semop)) | 310 | CALL(ABI(sys_semop, sys_oabi_semop)) |
311 | CALL(sys_semget) | 311 | CALL(sys_semget) |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index d401d908c463..964cd717506b 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -333,10 +333,14 @@ __pabt_svc: | |||
333 | @ from the exception stack | 333 | @ from the exception stack |
334 | 334 | ||
335 | #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) | 335 | #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) |
336 | #ifndef CONFIG_MMU | ||
337 | #warning "NPTL on non MMU needs fixing" | ||
338 | #else | ||
336 | @ make sure our user space atomic helper is aborted | 339 | @ make sure our user space atomic helper is aborted |
337 | cmp r2, #TASK_SIZE | 340 | cmp r2, #TASK_SIZE |
338 | bichs r3, r3, #PSR_Z_BIT | 341 | bichs r3, r3, #PSR_Z_BIT |
339 | #endif | 342 | #endif |
343 | #endif | ||
340 | 344 | ||
341 | @ | 345 | @ |
342 | @ We are now ready to fill in the remaining blanks on the stack: | 346 | @ We are now ready to fill in the remaining blanks on the stack: |
@@ -705,7 +709,12 @@ __kuser_memory_barrier: @ 0xffff0fa0 | |||
705 | * The C flag is also set if *ptr was changed to allow for assembly | 709 | * The C flag is also set if *ptr was changed to allow for assembly |
706 | * optimization in the calling code. | 710 | * optimization in the calling code. |
707 | * | 711 | * |
708 | * Note: this routine already includes memory barriers as needed. | 712 | * Notes: |
713 | * | ||
714 | * - This routine already includes memory barriers as needed. | ||
715 | * | ||
716 | * - A failure might be transient, i.e. it is possible, although unlikely, | ||
717 | * that "failure" be returned even if *ptr == oldval. | ||
709 | * | 718 | * |
710 | * For example, a user space atomic_add implementation could look like this: | 719 | * For example, a user space atomic_add implementation could look like this: |
711 | * | 720 | * |
@@ -756,12 +765,18 @@ __kuser_cmpxchg: @ 0xffff0fc0 | |||
756 | * exception happening just after the str instruction which would | 765 | * exception happening just after the str instruction which would |
757 | * clear the Z flag although the exchange was done. | 766 | * clear the Z flag although the exchange was done. |
758 | */ | 767 | */ |
768 | #ifdef CONFIG_MMU | ||
759 | teq ip, ip @ set Z flag | 769 | teq ip, ip @ set Z flag |
760 | ldr ip, [r2] @ load current val | 770 | ldr ip, [r2] @ load current val |
761 | add r3, r2, #1 @ prepare store ptr | 771 | add r3, r2, #1 @ prepare store ptr |
762 | teqeq ip, r0 @ compare with oldval if still allowed | 772 | teqeq ip, r0 @ compare with oldval if still allowed |
763 | streq r1, [r3, #-1]! @ store newval if still allowed | 773 | streq r1, [r3, #-1]! @ store newval if still allowed |
764 | subs r0, r2, r3 @ if r2 == r3 the str occured | 774 | subs r0, r2, r3 @ if r2 == r3 the str occured |
775 | #else | ||
776 | #warning "NPTL on non MMU needs fixing" | ||
777 | mov r0, #-1 | ||
778 | adds r0, r0, #0 | ||
779 | #endif | ||
765 | mov pc, lr | 780 | mov pc, lr |
766 | 781 | ||
767 | #else | 782 | #else |
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c index eafa8e5284af..9d4b76409c64 100644 --- a/arch/arm/kernel/sys_oabi-compat.c +++ b/arch/arm/kernel/sys_oabi-compat.c | |||
@@ -59,6 +59,16 @@ | |||
59 | * struct sembuf loses its padding with EABI. Since arrays of them are | 59 | * struct sembuf loses its padding with EABI. Since arrays of them are |
60 | * used they have to be copyed to remove the padding. Compatibility wrappers | 60 | * used they have to be copyed to remove the padding. Compatibility wrappers |
61 | * provided below. | 61 | * provided below. |
62 | * | ||
63 | * sys_bind: | ||
64 | * sys_connect: | ||
65 | * sys_sendmsg: | ||
66 | * sys_sendto: | ||
67 | * | ||
68 | * struct sockaddr_un loses its padding with EABI. Since the size of the | ||
69 | * structure is used as a validation test in unix_mkname(), we need to | ||
70 | * change the length argument to 110 whenever it is 112. Compatibility | ||
71 | * wrappers provided below. | ||
62 | */ | 72 | */ |
63 | 73 | ||
64 | #include <linux/syscalls.h> | 74 | #include <linux/syscalls.h> |
@@ -67,6 +77,7 @@ | |||
67 | #include <linux/fcntl.h> | 77 | #include <linux/fcntl.h> |
68 | #include <linux/eventpoll.h> | 78 | #include <linux/eventpoll.h> |
69 | #include <linux/sem.h> | 79 | #include <linux/sem.h> |
80 | #include <linux/socket.h> | ||
70 | #include <asm/ipc.h> | 81 | #include <asm/ipc.h> |
71 | #include <asm/uaccess.h> | 82 | #include <asm/uaccess.h> |
72 | 83 | ||
@@ -337,3 +348,63 @@ asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third, | |||
337 | return sys_ipc(call, first, second, third, ptr, fifth); | 348 | return sys_ipc(call, first, second, third, ptr, fifth); |
338 | } | 349 | } |
339 | } | 350 | } |
351 | |||
352 | asmlinkage long sys_oabi_bind(int fd, struct sockaddr __user *addr, int addrlen) | ||
353 | { | ||
354 | sa_family_t sa_family; | ||
355 | if (addrlen == 112 && | ||
356 | get_user(sa_family, &addr->sa_family) == 0 && | ||
357 | sa_family == AF_UNIX) | ||
358 | addrlen = 110; | ||
359 | return sys_bind(fd, addr, addrlen); | ||
360 | } | ||
361 | |||
362 | asmlinkage long sys_oabi_connect(int fd, struct sockaddr __user *addr, int addrlen) | ||
363 | { | ||
364 | sa_family_t sa_family; | ||
365 | if (addrlen == 112 && | ||
366 | get_user(sa_family, &addr->sa_family) == 0 && | ||
367 | sa_family == AF_UNIX) | ||
368 | addrlen = 110; | ||
369 | return sys_connect(fd, addr, addrlen); | ||
370 | } | ||
371 | |||
372 | asmlinkage long sys_oabi_sendto(int fd, void __user *buff, | ||
373 | size_t len, unsigned flags, | ||
374 | struct sockaddr __user *addr, | ||
375 | int addrlen) | ||
376 | { | ||
377 | sa_family_t sa_family; | ||
378 | if (addrlen == 112 && | ||
379 | get_user(sa_family, &addr->sa_family) == 0 && | ||
380 | sa_family == AF_UNIX) | ||
381 | addrlen = 110; | ||
382 | return sys_sendto(fd, buff, len, flags, addr, addrlen); | ||
383 | } | ||
384 | |||
385 | asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) | ||
386 | { | ||
387 | struct sockaddr __user *addr; | ||
388 | int msg_namelen; | ||
389 | sa_family_t sa_family; | ||
390 | if (msg && | ||
391 | get_user(msg_namelen, &msg->msg_namelen) == 0 && | ||
392 | msg_namelen == 112 && | ||
393 | get_user(addr, &msg->msg_name) == 0 && | ||
394 | get_user(sa_family, &addr->sa_family) == 0 && | ||
395 | sa_family == AF_UNIX) | ||
396 | { | ||
397 | /* | ||
398 | * HACK ALERT: there is a limit to how much backward bending | ||
399 | * we should do for what is actually a transitional | ||
400 | * compatibility layer. This already has known flaws with | ||
401 | * a few ioctls that we don't intend to fix. Therefore | ||
402 | * consider this blatent hack as another one... and take care | ||
403 | * to run for cover. In most cases it will "just work fine". | ||
404 | * If it doesn't, well, tough. | ||
405 | */ | ||
406 | put_user(110, &msg->msg_namelen); | ||
407 | } | ||
408 | return sys_sendmsg(fd, msg, flags); | ||
409 | } | ||
410 | |||