aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/compat.c')
-rw-r--r--kernel/compat.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/kernel/compat.c b/kernel/compat.c
index 2f672332430f..75573e5d27b0 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -22,6 +22,7 @@
22#include <linux/security.h> 22#include <linux/security.h>
23#include <linux/timex.h> 23#include <linux/timex.h>
24#include <linux/migrate.h> 24#include <linux/migrate.h>
25#include <linux/posix-timers.h>
25 26
26#include <asm/uaccess.h> 27#include <asm/uaccess.h>
27 28
@@ -601,6 +602,30 @@ long compat_sys_clock_getres(clockid_t which_clock,
601 return err; 602 return err;
602} 603}
603 604
605static long compat_clock_nanosleep_restart(struct restart_block *restart)
606{
607 long err;
608 mm_segment_t oldfs;
609 struct timespec tu;
610 struct compat_timespec *rmtp = (struct compat_timespec *)(restart->arg1);
611
612 restart->arg1 = (unsigned long) &tu;
613 oldfs = get_fs();
614 set_fs(KERNEL_DS);
615 err = clock_nanosleep_restart(restart);
616 set_fs(oldfs);
617
618 if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
619 put_compat_timespec(&tu, rmtp))
620 return -EFAULT;
621
622 if (err == -ERESTART_RESTARTBLOCK) {
623 restart->fn = compat_clock_nanosleep_restart;
624 restart->arg1 = (unsigned long) rmtp;
625 }
626 return err;
627}
628
604long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, 629long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
605 struct compat_timespec __user *rqtp, 630 struct compat_timespec __user *rqtp,
606 struct compat_timespec __user *rmtp) 631 struct compat_timespec __user *rmtp)
@@ -608,6 +633,7 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
608 long err; 633 long err;
609 mm_segment_t oldfs; 634 mm_segment_t oldfs;
610 struct timespec in, out; 635 struct timespec in, out;
636 struct restart_block *restart;
611 637
612 if (get_compat_timespec(&in, rqtp)) 638 if (get_compat_timespec(&in, rqtp))
613 return -EFAULT; 639 return -EFAULT;
@@ -618,9 +644,16 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
618 (struct timespec __user *) &in, 644 (struct timespec __user *) &in,
619 (struct timespec __user *) &out); 645 (struct timespec __user *) &out);
620 set_fs(oldfs); 646 set_fs(oldfs);
647
621 if ((err == -ERESTART_RESTARTBLOCK) && rmtp && 648 if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
622 put_compat_timespec(&out, rmtp)) 649 put_compat_timespec(&out, rmtp))
623 return -EFAULT; 650 return -EFAULT;
651
652 if (err == -ERESTART_RESTARTBLOCK) {
653 restart = &current_thread_info()->restart_block;
654 restart->fn = compat_clock_nanosleep_restart;
655 restart->arg1 = (unsigned long) rmtp;
656 }
624 return err; 657 return err;
625} 658}
626 659
@@ -730,17 +763,10 @@ void
730sigset_from_compat (sigset_t *set, compat_sigset_t *compat) 763sigset_from_compat (sigset_t *set, compat_sigset_t *compat)
731{ 764{
732 switch (_NSIG_WORDS) { 765 switch (_NSIG_WORDS) {
733#if defined (__COMPAT_ENDIAN_SWAP__)
734 case 4: set->sig[3] = compat->sig[7] | (((long)compat->sig[6]) << 32 );
735 case 3: set->sig[2] = compat->sig[5] | (((long)compat->sig[4]) << 32 );
736 case 2: set->sig[1] = compat->sig[3] | (((long)compat->sig[2]) << 32 );
737 case 1: set->sig[0] = compat->sig[1] | (((long)compat->sig[0]) << 32 );
738#else
739 case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32 ); 766 case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32 );
740 case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32 ); 767 case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32 );
741 case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32 ); 768 case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32 );
742 case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32 ); 769 case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32 );
743#endif
744 } 770 }
745} 771}
746 772