diff options
-rw-r--r-- | fs/select.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/fs/select.c b/fs/select.c index e2fd58f8f1db..7dede89658f5 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -714,10 +714,28 @@ out_fds: | |||
714 | return err; | 714 | return err; |
715 | } | 715 | } |
716 | 716 | ||
717 | static long do_restart_poll(struct restart_block *restart_block) | ||
718 | { | ||
719 | struct pollfd __user *ufds = (struct pollfd __user*)restart_block->arg0; | ||
720 | int nfds = restart_block->arg1; | ||
721 | s64 timeout = ((s64)restart_block->arg3<<32) | (s64)restart_block->arg2; | ||
722 | int ret; | ||
723 | |||
724 | ret = do_sys_poll(ufds, nfds, &timeout); | ||
725 | if (ret == -EINTR) { | ||
726 | restart_block->fn = do_restart_poll; | ||
727 | restart_block->arg2 = timeout & 0xFFFFFFFF; | ||
728 | restart_block->arg3 = (u64)timeout >> 32; | ||
729 | ret = -ERESTART_RESTARTBLOCK; | ||
730 | } | ||
731 | return ret; | ||
732 | } | ||
733 | |||
717 | asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, | 734 | asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, |
718 | long timeout_msecs) | 735 | long timeout_msecs) |
719 | { | 736 | { |
720 | s64 timeout_jiffies; | 737 | s64 timeout_jiffies; |
738 | int ret; | ||
721 | 739 | ||
722 | if (timeout_msecs > 0) { | 740 | if (timeout_msecs > 0) { |
723 | #if HZ > 1000 | 741 | #if HZ > 1000 |
@@ -732,7 +750,18 @@ asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, | |||
732 | timeout_jiffies = timeout_msecs; | 750 | timeout_jiffies = timeout_msecs; |
733 | } | 751 | } |
734 | 752 | ||
735 | return do_sys_poll(ufds, nfds, &timeout_jiffies); | 753 | ret = do_sys_poll(ufds, nfds, &timeout_jiffies); |
754 | if (ret == -EINTR) { | ||
755 | struct restart_block *restart_block; | ||
756 | restart_block = ¤t_thread_info()->restart_block; | ||
757 | restart_block->fn = do_restart_poll; | ||
758 | restart_block->arg0 = (unsigned long)ufds; | ||
759 | restart_block->arg1 = nfds; | ||
760 | restart_block->arg2 = timeout_jiffies & 0xFFFFFFFF; | ||
761 | restart_block->arg3 = (u64)timeout_jiffies >> 32; | ||
762 | ret = -ERESTART_RESTARTBLOCK; | ||
763 | } | ||
764 | return ret; | ||
736 | } | 765 | } |
737 | 766 | ||
738 | #ifdef TIF_RESTORE_SIGMASK | 767 | #ifdef TIF_RESTORE_SIGMASK |