diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-17 11:58:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-17 11:58:04 -0400 |
commit | 57a8ec387e1441ea5e1232bc0749fb99a8cba7e7 (patch) | |
tree | b5fb03fc6bc5754de8b5b1f8b0e4f36d67c8315c /fs/select.c | |
parent | 0a8ad0ffa4d80a544f6cbff703bf6394339afcdf (diff) | |
parent | 43e11fa2d1d3b6e35629fa556eb7d571edba2010 (diff) |
Merge branch 'akpm' (patches from Andrew)
Merge more updates from Andrew Morton:
"VM:
- z3fold fixes and enhancements by Henry Burns and Vitaly Wool
- more accurate reclaimed slab caches calculations by Yafang Shao
- fix MAP_UNINITIALIZED UAPI symbol to not depend on config, by
Christoph Hellwig
- !CONFIG_MMU fixes by Christoph Hellwig
- new novmcoredd parameter to omit device dumps from vmcore, by
Kairui Song
- new test_meminit module for testing heap and pagealloc
initialization, by Alexander Potapenko
- ioremap improvements for huge mappings, by Anshuman Khandual
- generalize kprobe page fault handling, by Anshuman Khandual
- device-dax hotplug fixes and improvements, by Pavel Tatashin
- enable synchronous DAX fault on powerpc, by Aneesh Kumar K.V
- add pte_devmap() support for arm64, by Robin Murphy
- unify locked_vm accounting with a helper, by Daniel Jordan
- several misc fixes
core/lib:
- new typeof_member() macro including some users, by Alexey Dobriyan
- make BIT() and GENMASK() available in asm, by Masahiro Yamada
- changed LIST_POISON2 on x86_64 to 0xdead000000000122 for better
code generation, by Alexey Dobriyan
- rbtree code size optimizations, by Michel Lespinasse
- convert struct pid count to refcount_t, by Joel Fernandes
get_maintainer.pl:
- add --no-moderated switch to skip moderated ML's, by Joe Perches
misc:
- ptrace PTRACE_GET_SYSCALL_INFO interface
- coda updates
- gdb scripts, various"
[ Using merge message suggestion from Vlastimil Babka, with some editing - Linus ]
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (100 commits)
fs/select.c: use struct_size() in kmalloc()
mm: add account_locked_vm utility function
arm64: mm: implement pte_devmap support
mm: introduce ARCH_HAS_PTE_DEVMAP
mm: clean up is_device_*_page() definitions
mm/mmap: move common defines to mman-common.h
mm: move MAP_SYNC to asm-generic/mman-common.h
device-dax: "Hotremove" persistent memory that is used like normal RAM
mm/hotplug: make remove_memory() interface usable
device-dax: fix memory and resource leak if hotplug fails
include/linux/lz4.h: fix spelling and copy-paste errors in documentation
ipc/mqueue.c: only perform resource calculation if user valid
include/asm-generic/bug.h: fix "cut here" for WARN_ON for __WARN_TAINT architectures
scripts/gdb: add helpers to find and list devices
scripts/gdb: add lx-genpd-summary command
drivers/pps/pps.c: clear offset flags in PPS_SETPARAMS ioctl
kernel/pid.c: convert struct pid count to refcount_t
drivers/rapidio/devices/rio_mport_cdev.c: NUL terminate some strings
select: shift restore_saved_sigmask_unless() into poll_select_copy_remaining()
select: change do_poll() to return -ERESTARTNOHAND rather than -EINTR
...
Diffstat (limited to 'fs/select.c')
-rw-r--r-- | fs/select.c | 96 |
1 files changed, 25 insertions, 71 deletions
diff --git a/fs/select.c b/fs/select.c index a4d8f6e8b63c..53a0c149f528 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -294,12 +294,14 @@ enum poll_time_type { | |||
294 | PT_OLD_TIMESPEC = 3, | 294 | PT_OLD_TIMESPEC = 3, |
295 | }; | 295 | }; |
296 | 296 | ||
297 | static int poll_select_copy_remaining(struct timespec64 *end_time, | 297 | static int poll_select_finish(struct timespec64 *end_time, |
298 | void __user *p, | 298 | void __user *p, |
299 | enum poll_time_type pt_type, int ret) | 299 | enum poll_time_type pt_type, int ret) |
300 | { | 300 | { |
301 | struct timespec64 rts; | 301 | struct timespec64 rts; |
302 | 302 | ||
303 | restore_saved_sigmask_unless(ret == -ERESTARTNOHAND); | ||
304 | |||
303 | if (!p) | 305 | if (!p) |
304 | return ret; | 306 | return ret; |
305 | 307 | ||
@@ -714,9 +716,7 @@ static int kern_select(int n, fd_set __user *inp, fd_set __user *outp, | |||
714 | } | 716 | } |
715 | 717 | ||
716 | ret = core_sys_select(n, inp, outp, exp, to); | 718 | ret = core_sys_select(n, inp, outp, exp, to); |
717 | ret = poll_select_copy_remaining(&end_time, tvp, PT_TIMEVAL, ret); | 719 | return poll_select_finish(&end_time, tvp, PT_TIMEVAL, ret); |
718 | |||
719 | return ret; | ||
720 | } | 720 | } |
721 | 721 | ||
722 | SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp, | 722 | SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp, |
@@ -730,7 +730,6 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, | |||
730 | const sigset_t __user *sigmask, size_t sigsetsize, | 730 | const sigset_t __user *sigmask, size_t sigsetsize, |
731 | enum poll_time_type type) | 731 | enum poll_time_type type) |
732 | { | 732 | { |
733 | sigset_t ksigmask, sigsaved; | ||
734 | struct timespec64 ts, end_time, *to = NULL; | 733 | struct timespec64 ts, end_time, *to = NULL; |
735 | int ret; | 734 | int ret; |
736 | 735 | ||
@@ -753,15 +752,12 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, | |||
753 | return -EINVAL; | 752 | return -EINVAL; |
754 | } | 753 | } |
755 | 754 | ||
756 | ret = set_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize); | 755 | ret = set_user_sigmask(sigmask, sigsetsize); |
757 | if (ret) | 756 | if (ret) |
758 | return ret; | 757 | return ret; |
759 | 758 | ||
760 | ret = core_sys_select(n, inp, outp, exp, to); | 759 | ret = core_sys_select(n, inp, outp, exp, to); |
761 | restore_user_sigmask(sigmask, &sigsaved, ret == -ERESTARTNOHAND); | 760 | return poll_select_finish(&end_time, tsp, type, ret); |
762 | ret = poll_select_copy_remaining(&end_time, tsp, type, ret); | ||
763 | |||
764 | return ret; | ||
765 | } | 761 | } |
766 | 762 | ||
767 | /* | 763 | /* |
@@ -926,7 +922,7 @@ static int do_poll(struct poll_list *list, struct poll_wqueues *wait, | |||
926 | if (!count) { | 922 | if (!count) { |
927 | count = wait->error; | 923 | count = wait->error; |
928 | if (signal_pending(current)) | 924 | if (signal_pending(current)) |
929 | count = -EINTR; | 925 | count = -ERESTARTNOHAND; |
930 | } | 926 | } |
931 | if (count || timed_out) | 927 | if (count || timed_out) |
932 | break; | 928 | break; |
@@ -965,7 +961,7 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, | |||
965 | struct timespec64 *end_time) | 961 | struct timespec64 *end_time) |
966 | { | 962 | { |
967 | struct poll_wqueues table; | 963 | struct poll_wqueues table; |
968 | int err = -EFAULT, fdcount, len, size; | 964 | int err = -EFAULT, fdcount, len; |
969 | /* Allocate small arguments on the stack to save memory and be | 965 | /* Allocate small arguments on the stack to save memory and be |
970 | faster - use long to make sure the buffer is aligned properly | 966 | faster - use long to make sure the buffer is aligned properly |
971 | on 64 bit archs to avoid unaligned access */ | 967 | on 64 bit archs to avoid unaligned access */ |
@@ -993,8 +989,8 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, | |||
993 | break; | 989 | break; |
994 | 990 | ||
995 | len = min(todo, POLLFD_PER_PAGE); | 991 | len = min(todo, POLLFD_PER_PAGE); |
996 | size = sizeof(struct poll_list) + sizeof(struct pollfd) * len; | 992 | walk = walk->next = kmalloc(struct_size(walk, entries, len), |
997 | walk = walk->next = kmalloc(size, GFP_KERNEL); | 993 | GFP_KERNEL); |
998 | if (!walk) { | 994 | if (!walk) { |
999 | err = -ENOMEM; | 995 | err = -ENOMEM; |
1000 | goto out_fds; | 996 | goto out_fds; |
@@ -1041,7 +1037,7 @@ static long do_restart_poll(struct restart_block *restart_block) | |||
1041 | 1037 | ||
1042 | ret = do_sys_poll(ufds, nfds, to); | 1038 | ret = do_sys_poll(ufds, nfds, to); |
1043 | 1039 | ||
1044 | if (ret == -EINTR) { | 1040 | if (ret == -ERESTARTNOHAND) { |
1045 | restart_block->fn = do_restart_poll; | 1041 | restart_block->fn = do_restart_poll; |
1046 | ret = -ERESTART_RESTARTBLOCK; | 1042 | ret = -ERESTART_RESTARTBLOCK; |
1047 | } | 1043 | } |
@@ -1062,7 +1058,7 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds, | |||
1062 | 1058 | ||
1063 | ret = do_sys_poll(ufds, nfds, to); | 1059 | ret = do_sys_poll(ufds, nfds, to); |
1064 | 1060 | ||
1065 | if (ret == -EINTR) { | 1061 | if (ret == -ERESTARTNOHAND) { |
1066 | struct restart_block *restart_block; | 1062 | struct restart_block *restart_block; |
1067 | 1063 | ||
1068 | restart_block = ¤t->restart_block; | 1064 | restart_block = ¤t->restart_block; |
@@ -1086,7 +1082,6 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, | |||
1086 | struct __kernel_timespec __user *, tsp, const sigset_t __user *, sigmask, | 1082 | struct __kernel_timespec __user *, tsp, const sigset_t __user *, sigmask, |
1087 | size_t, sigsetsize) | 1083 | size_t, sigsetsize) |
1088 | { | 1084 | { |
1089 | sigset_t ksigmask, sigsaved; | ||
1090 | struct timespec64 ts, end_time, *to = NULL; | 1085 | struct timespec64 ts, end_time, *to = NULL; |
1091 | int ret; | 1086 | int ret; |
1092 | 1087 | ||
@@ -1099,20 +1094,12 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, | |||
1099 | return -EINVAL; | 1094 | return -EINVAL; |
1100 | } | 1095 | } |
1101 | 1096 | ||
1102 | ret = set_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize); | 1097 | ret = set_user_sigmask(sigmask, sigsetsize); |
1103 | if (ret) | 1098 | if (ret) |
1104 | return ret; | 1099 | return ret; |
1105 | 1100 | ||
1106 | ret = do_sys_poll(ufds, nfds, to); | 1101 | ret = do_sys_poll(ufds, nfds, to); |
1107 | 1102 | return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret); | |
1108 | restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR); | ||
1109 | /* We can restart this syscall, usually */ | ||
1110 | if (ret == -EINTR) | ||
1111 | ret = -ERESTARTNOHAND; | ||
1112 | |||
1113 | ret = poll_select_copy_remaining(&end_time, tsp, PT_TIMESPEC, ret); | ||
1114 | |||
1115 | return ret; | ||
1116 | } | 1103 | } |
1117 | 1104 | ||
1118 | #if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT) | 1105 | #if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT) |
@@ -1121,7 +1108,6 @@ SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds, | |||
1121 | struct old_timespec32 __user *, tsp, const sigset_t __user *, sigmask, | 1108 | struct old_timespec32 __user *, tsp, const sigset_t __user *, sigmask, |
1122 | size_t, sigsetsize) | 1109 | size_t, sigsetsize) |
1123 | { | 1110 | { |
1124 | sigset_t ksigmask, sigsaved; | ||
1125 | struct timespec64 ts, end_time, *to = NULL; | 1111 | struct timespec64 ts, end_time, *to = NULL; |
1126 | int ret; | 1112 | int ret; |
1127 | 1113 | ||
@@ -1134,20 +1120,12 @@ SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds, | |||
1134 | return -EINVAL; | 1120 | return -EINVAL; |
1135 | } | 1121 | } |
1136 | 1122 | ||
1137 | ret = set_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize); | 1123 | ret = set_user_sigmask(sigmask, sigsetsize); |
1138 | if (ret) | 1124 | if (ret) |
1139 | return ret; | 1125 | return ret; |
1140 | 1126 | ||
1141 | ret = do_sys_poll(ufds, nfds, to); | 1127 | ret = do_sys_poll(ufds, nfds, to); |
1142 | 1128 | return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret); | |
1143 | restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR); | ||
1144 | /* We can restart this syscall, usually */ | ||
1145 | if (ret == -EINTR) | ||
1146 | ret = -ERESTARTNOHAND; | ||
1147 | |||
1148 | ret = poll_select_copy_remaining(&end_time, tsp, PT_OLD_TIMESPEC, ret); | ||
1149 | |||
1150 | return ret; | ||
1151 | } | 1129 | } |
1152 | #endif | 1130 | #endif |
1153 | 1131 | ||
@@ -1284,9 +1262,7 @@ static int do_compat_select(int n, compat_ulong_t __user *inp, | |||
1284 | } | 1262 | } |
1285 | 1263 | ||
1286 | ret = compat_core_sys_select(n, inp, outp, exp, to); | 1264 | ret = compat_core_sys_select(n, inp, outp, exp, to); |
1287 | ret = poll_select_copy_remaining(&end_time, tvp, PT_OLD_TIMEVAL, ret); | 1265 | return poll_select_finish(&end_time, tvp, PT_OLD_TIMEVAL, ret); |
1288 | |||
1289 | return ret; | ||
1290 | } | 1266 | } |
1291 | 1267 | ||
1292 | COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp, | 1268 | COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp, |
@@ -1319,7 +1295,6 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp, | |||
1319 | void __user *tsp, compat_sigset_t __user *sigmask, | 1295 | void __user *tsp, compat_sigset_t __user *sigmask, |
1320 | compat_size_t sigsetsize, enum poll_time_type type) | 1296 | compat_size_t sigsetsize, enum poll_time_type type) |
1321 | { | 1297 | { |
1322 | sigset_t ksigmask, sigsaved; | ||
1323 | struct timespec64 ts, end_time, *to = NULL; | 1298 | struct timespec64 ts, end_time, *to = NULL; |
1324 | int ret; | 1299 | int ret; |
1325 | 1300 | ||
@@ -1342,15 +1317,12 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp, | |||
1342 | return -EINVAL; | 1317 | return -EINVAL; |
1343 | } | 1318 | } |
1344 | 1319 | ||
1345 | ret = set_compat_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize); | 1320 | ret = set_compat_user_sigmask(sigmask, sigsetsize); |
1346 | if (ret) | 1321 | if (ret) |
1347 | return ret; | 1322 | return ret; |
1348 | 1323 | ||
1349 | ret = compat_core_sys_select(n, inp, outp, exp, to); | 1324 | ret = compat_core_sys_select(n, inp, outp, exp, to); |
1350 | restore_user_sigmask(sigmask, &sigsaved, ret == -ERESTARTNOHAND); | 1325 | return poll_select_finish(&end_time, tsp, type, ret); |
1351 | ret = poll_select_copy_remaining(&end_time, tsp, type, ret); | ||
1352 | |||
1353 | return ret; | ||
1354 | } | 1326 | } |
1355 | 1327 | ||
1356 | COMPAT_SYSCALL_DEFINE6(pselect6_time64, int, n, compat_ulong_t __user *, inp, | 1328 | COMPAT_SYSCALL_DEFINE6(pselect6_time64, int, n, compat_ulong_t __user *, inp, |
@@ -1402,7 +1374,6 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, | |||
1402 | unsigned int, nfds, struct old_timespec32 __user *, tsp, | 1374 | unsigned int, nfds, struct old_timespec32 __user *, tsp, |
1403 | const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) | 1375 | const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) |
1404 | { | 1376 | { |
1405 | sigset_t ksigmask, sigsaved; | ||
1406 | struct timespec64 ts, end_time, *to = NULL; | 1377 | struct timespec64 ts, end_time, *to = NULL; |
1407 | int ret; | 1378 | int ret; |
1408 | 1379 | ||
@@ -1415,20 +1386,12 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, | |||
1415 | return -EINVAL; | 1386 | return -EINVAL; |
1416 | } | 1387 | } |
1417 | 1388 | ||
1418 | ret = set_compat_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize); | 1389 | ret = set_compat_user_sigmask(sigmask, sigsetsize); |
1419 | if (ret) | 1390 | if (ret) |
1420 | return ret; | 1391 | return ret; |
1421 | 1392 | ||
1422 | ret = do_sys_poll(ufds, nfds, to); | 1393 | ret = do_sys_poll(ufds, nfds, to); |
1423 | 1394 | return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret); | |
1424 | restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR); | ||
1425 | /* We can restart this syscall, usually */ | ||
1426 | if (ret == -EINTR) | ||
1427 | ret = -ERESTARTNOHAND; | ||
1428 | |||
1429 | ret = poll_select_copy_remaining(&end_time, tsp, PT_OLD_TIMESPEC, ret); | ||
1430 | |||
1431 | return ret; | ||
1432 | } | 1395 | } |
1433 | #endif | 1396 | #endif |
1434 | 1397 | ||
@@ -1437,7 +1400,6 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds, | |||
1437 | unsigned int, nfds, struct __kernel_timespec __user *, tsp, | 1400 | unsigned int, nfds, struct __kernel_timespec __user *, tsp, |
1438 | const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) | 1401 | const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) |
1439 | { | 1402 | { |
1440 | sigset_t ksigmask, sigsaved; | ||
1441 | struct timespec64 ts, end_time, *to = NULL; | 1403 | struct timespec64 ts, end_time, *to = NULL; |
1442 | int ret; | 1404 | int ret; |
1443 | 1405 | ||
@@ -1450,20 +1412,12 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds, | |||
1450 | return -EINVAL; | 1412 | return -EINVAL; |
1451 | } | 1413 | } |
1452 | 1414 | ||
1453 | ret = set_compat_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize); | 1415 | ret = set_compat_user_sigmask(sigmask, sigsetsize); |
1454 | if (ret) | 1416 | if (ret) |
1455 | return ret; | 1417 | return ret; |
1456 | 1418 | ||
1457 | ret = do_sys_poll(ufds, nfds, to); | 1419 | ret = do_sys_poll(ufds, nfds, to); |
1458 | 1420 | return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret); | |
1459 | restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR); | ||
1460 | /* We can restart this syscall, usually */ | ||
1461 | if (ret == -EINTR) | ||
1462 | ret = -ERESTARTNOHAND; | ||
1463 | |||
1464 | ret = poll_select_copy_remaining(&end_time, tsp, PT_TIMESPEC, ret); | ||
1465 | |||
1466 | return ret; | ||
1467 | } | 1421 | } |
1468 | 1422 | ||
1469 | #endif | 1423 | #endif |