aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/select.c31
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
717static 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
717asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, 734asmlinkage 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 = &current_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