diff options
Diffstat (limited to 'kernel/compat.c')
| -rw-r--r-- | kernel/compat.c | 33 | 
1 files changed, 33 insertions, 0 deletions
| diff --git a/kernel/compat.c b/kernel/compat.c index 126dee9530aa..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 | ||
