diff options
Diffstat (limited to 'kernel/compat.c')
| -rw-r--r-- | kernel/compat.c | 40 |
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 | ||
| 605 | static 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 | |||
| 604 | long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, | 629 | long 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 = ¤t_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 | |||
| 730 | sigset_from_compat (sigset_t *set, compat_sigset_t *compat) | 763 | sigset_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 | ||
