From f00d03445c29bafa0d8be8502f04d21d63a22300 Mon Sep 17 00:00:00 2001 From: Tomoki Shirasawa Date: Wed, 25 Dec 2019 10:56:44 +0900 Subject: [PATCH] epoll_pwait, ppoll, pselect: add to process sigmask Change-Id: I6aa1db3b4c6ad81a8b5926fa87fc645269b103b6 Refs: #1361 --- arch/arm64/kernel/include/syscall_list.h | 6 +- arch/x86_64/kernel/include/syscall_list.h | 6 +- kernel/syscall.c | 69 +++++++++++++++++++ test/issues/1361/C1361.sh | 22 ++++++ test/issues/1361/C1361T01.c | 63 +++++++++++++++++ test/issues/1361/C1361_arm64.txt | 83 +++++++++++++++++++++++ test/issues/1361/C1361_x86_64.txt | 83 +++++++++++++++++++++++ test/issues/1361/Makefile | 13 ++++ test/issues/1361/README | 23 +++++++ 9 files changed, 362 insertions(+), 6 deletions(-) create mode 100644 test/issues/1361/C1361.sh create mode 100644 test/issues/1361/C1361T01.c create mode 100644 test/issues/1361/C1361_arm64.txt create mode 100644 test/issues/1361/C1361_x86_64.txt create mode 100644 test/issues/1361/Makefile create mode 100644 test/issues/1361/README diff --git a/arch/arm64/kernel/include/syscall_list.h b/arch/arm64/kernel/include/syscall_list.h index fd868af7..19f286c6 100644 --- a/arch/arm64/kernel/include/syscall_list.h +++ b/arch/arm64/kernel/include/syscall_list.h @@ -2,7 +2,7 @@ SYSCALL_DELEGATED(4, io_getevents) SYSCALL_DELEGATED(17, getcwd) -SYSCALL_DELEGATED(22, epoll_pwait) +SYSCALL_HANDLED(22, epoll_pwait) SYSCALL_DELEGATED(25, fcntl) SYSCALL_HANDLED(29, ioctl) SYSCALL_DELEGATED(35, unlinkat) @@ -17,8 +17,8 @@ SYSCALL_DELEGATED(64, write) SYSCALL_DELEGATED(66, writev) SYSCALL_DELEGATED(67, pread64) SYSCALL_DELEGATED(68, pwrite64) -SYSCALL_DELEGATED(72, pselect6) -SYSCALL_DELEGATED(73, ppoll) +SYSCALL_HANDLED(72, pselect6) +SYSCALL_HANDLED(73, ppoll) SYSCALL_HANDLED(74, signalfd4) SYSCALL_DELEGATED(78, readlinkat) SYSCALL_DELEGATED(80, fstat) diff --git a/arch/x86_64/kernel/include/syscall_list.h b/arch/x86_64/kernel/include/syscall_list.h index e0298446..b6bf4d55 100644 --- a/arch/x86_64/kernel/include/syscall_list.h +++ b/arch/x86_64/kernel/include/syscall_list.h @@ -147,11 +147,11 @@ SYSCALL_DELEGATED(266, symlinkat) SYSCALL_DELEGATED(267, readlinkat) SYSCALL_DELEGATED(268, fchmodat) SYSCALL_DELEGATED(269, faccessat) -SYSCALL_DELEGATED(270, pselect6) -SYSCALL_DELEGATED(271, ppoll) +SYSCALL_HANDLED(270, pselect6) +SYSCALL_HANDLED(271, ppoll) SYSCALL_HANDLED(273, set_robust_list) SYSCALL_HANDLED(279, move_pages) -SYSCALL_DELEGATED(281, epoll_pwait) +SYSCALL_HANDLED(281, epoll_pwait) SYSCALL_HANDLED(282, signalfd) SYSCALL_HANDLED(289, signalfd4) #ifdef ENABLE_PERF diff --git a/kernel/syscall.c b/kernel/syscall.c index 1d8bb29e..d8fbf654 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -3669,6 +3669,75 @@ SYSCALL_DECLARE(fcntl) return rc; } +SYSCALL_DECLARE(epoll_pwait) +{ + long rc; + sigset_t *set = (sigset_t *)ihk_mc_syscall_arg4(ctx); + __sigset_t oldset; + __sigset_t wset; + struct thread *thread = cpu_local_var(current); + + oldset = thread->sigmask.__val[0]; + if (set) { + if (copy_from_user(&wset, set->__val, sizeof(wset))) { + return -EFAULT; + } + thread->sigmask.__val[0] = wset; + } + rc = syscall_generic_forwarding(__NR_epoll_pwait, ctx); + thread->sigmask.__val[0] = oldset; + + return rc; +} + +SYSCALL_DECLARE(ppoll) +{ + long rc; + sigset_t *set = (sigset_t *)ihk_mc_syscall_arg3(ctx); + __sigset_t oldset; + __sigset_t wset; + struct thread *thread = cpu_local_var(current); + + oldset = thread->sigmask.__val[0]; + if (set) { + if (copy_from_user(&wset, set->__val, sizeof(wset))) { + return -EFAULT; + } + thread->sigmask.__val[0] = wset; + } + rc = syscall_generic_forwarding(__NR_ppoll, ctx); + thread->sigmask.__val[0] = oldset; + + return rc; +} + +SYSCALL_DECLARE(pselect6) +{ + long rc; + sigset_t **_set = (sigset_t **)ihk_mc_syscall_arg5(ctx); + sigset_t *set = NULL; + __sigset_t oldset; + __sigset_t wset; + struct thread *thread = cpu_local_var(current); + + if (_set) { + if (copy_from_user(&set, _set, sizeof(void *))) { + return -EFAULT; + } + } + oldset = thread->sigmask.__val[0]; + if (set) { + if (copy_from_user(&wset, set->__val, sizeof(wset))) { + return -EFAULT; + } + thread->sigmask.__val[0] = wset; + } + rc = syscall_generic_forwarding(__NR_pselect6, ctx); + thread->sigmask.__val[0] = oldset; + + return rc; +} + SYSCALL_DECLARE(rt_sigprocmask) { int how = ihk_mc_syscall_arg0(ctx); diff --git a/test/issues/1361/C1361.sh b/test/issues/1361/C1361.sh new file mode 100644 index 00000000..ea02e5ec --- /dev/null +++ b/test/issues/1361/C1361.sh @@ -0,0 +1,22 @@ +#!/bin/sh +USELTP=1 +USEOSTEST=0 + +. ../../common.sh + +################################################################################ +uname -m +$MCEXEC ./C1361T01 + +for i in ppoll01:02 epoll_pwait01:03 pselect01:04 pselect03:05; do + tp=`echo $i|sed 's/:.*//'` + id=`echo $i|sed 's/.*://'` + sudo PATH=$PATH:$LTPBIN $MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt + ok=`grep PASS $tp.txt | wc -l` + ng=`grep FAIL $tp.txt | wc -l` + if [ $ng = 0 ]; then + echo "*** C1361T$id: $tp PASS ($ok)" + else + echo "*** C1361T$id: $tp FAIL (ok=$ok ng=%ng)" + fi +done diff --git a/test/issues/1361/C1361T01.c b/test/issues/1361/C1361T01.c new file mode 100644 index 00000000..15c43a78 --- /dev/null +++ b/test/issues/1361/C1361T01.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int sig; + +void +usr1(int s) +{ + sig = 1; +} + +void +usr2(int s) +{ + if (sig == 1) { + printf("*** C1361T01: FAIL : BAD USR1\n"); + exit(1); + } + printf("*** C1361T01: PASS\n"); + exit(0); +} + +int +main(int argc, char **argv) +{ + pid_t pid; + int st; + + if ((pid = fork()) == 0) { + sigset_t mask; + struct timespec to; + int rc; + + sigprocmask(0, NULL, &mask); + sigaddset(&mask, SIGUSR1); + signal(SIGUSR1, usr1); + signal(SIGUSR2, usr2); + to.tv_sec = 3; + to.tv_nsec = 0; + rc = pselect(0, NULL, NULL, NULL, &to, &mask); + if (rc == -1 && errno == EINTR) { + printf("*** C1361T01: FAIL : BAD SIGNAL\n"); + exit(1); + } + printf("*** C1361T01 FAIL: : timeout\n"); + exit(2); + } + sleep(1); + kill(pid, SIGUSR1); + sleep(1); + kill(pid, SIGUSR2); + while (waitpid(pid, &st, 0) == -1 && errno == EINTR) + ; + exit(0); +} diff --git a/test/issues/1361/C1361_arm64.txt b/test/issues/1361/C1361_arm64.txt new file mode 100644 index 00000000..31d2b61c --- /dev/null +++ b/test/issues/1361/C1361_arm64.txt @@ -0,0 +1,83 @@ +Script started on 2020-01-06 07:21:17+00:00 +bash-4.4$ make test +gcc C1361T01.c -o C1361T01 +sh ./C1361.sh +mcstop+release.sh ... done +mcreboot.sh -c 2-7,10-15 -m 2G@0 -O ... done +aarch64 +*** C1361T01: PASS +tst_test.c:1072: INFO: Timeout per run is 0h 05m 00s +ppoll01.c:221: INFO: case NORMAL +ppoll01.c:252: PASS: revents=0x0005 +ppoll01.c:258: PASS: ret: 1 +ppoll01.c:221: INFO: case MASK_SIGNAL +ppoll01.c:258: PASS: ret: 0 +ppoll01.c:221: INFO: case TIMEOUT +ppoll01.c:258: PASS: ret: 0 +ppoll01.c:221: INFO: case FD_ALREADY_CLOSED +ppoll01.c:252: PASS: revents=0x0020 +ppoll01.c:258: PASS: ret: 1 +ppoll01.c:221: INFO: case SEND_SIGINT +ppoll01.c:261: PASS: ret: -1, errno: EINTR (4) +ppoll01.c:221: INFO: case SEND_SIGINT_RACE_TEST +ppoll01.c:261: PASS: ret: -1, errno: EINTR (4) +ppoll01.c:221: INFO: case INVALID_NFDS +ppoll01.c:261: PASS: ret: -1, errno: EINVAL (22) +ppoll01.c:221: INFO: case INVALID_FDS +ppoll01.c:261: PASS: ret: -1, errno: EFAULT (14) + +Summary: +passed 10 +failed 0 +skipped 0 +warnings 0 +*** C1361T02: ppoll01 PASS (10) +epoll_pwait01 1 TPASS : epoll_pwait(sigmask) blocked signal +epoll_pwait01 0 TINFO : Child process returned TPASS +epoll_pwait01 2 TPASS : epoll_wait() failed as expected: TEST_ERRNO=EINTR(4): Interrupted system call +epoll_pwait01 0 TINFO : Child process returned TPASS +*** C1361T03: epoll_pwait01 PASS (4) +tst_test.c:1072: INFO: Timeout per run is 0h 05m 00s +tst_timer_test.c:356: INFO: CLOCK_MONOTONIC resolution 1ns +tst_timer_test.c:368: INFO: prctl(PR_GET_TIMERSLACK) = 50us +tst_timer_test.c:275: INFO: pselect() sleeping for 1000us 500 iterations, threshold 450.01us +tst_timer_test.c:318: INFO: min 1301us, max 1435us, median 1347us, trunc mean 1347.14us (discarded 25) +tst_timer_test.c:333: PASS: Measured times are within thresholds +tst_timer_test.c:275: INFO: pselect() sleeping for 2000us 500 iterations, threshold 450.01us +tst_timer_test.c:318: INFO: min 2338us, max 2423us, median 2348us, trunc mean 2348.02us (discarded 25) +tst_timer_test.c:333: PASS: Measured times are within thresholds +tst_timer_test.c:275: INFO: pselect() sleeping for 5000us 300 iterations, threshold 450.04us +tst_timer_test.c:318: INFO: min 5341us, max 5433us, median 5349us, trunc mean 5349.26us (discarded 15) +tst_timer_test.c:333: PASS: Measured times are within thresholds +tst_timer_test.c:275: INFO: pselect() sleeping for 10000us 100 iterations, threshold 450.33us +tst_timer_test.c:318: INFO: min 10344us, max 10413us, median 10353us, trunc mean 10353.22us (discarded 5) +tst_timer_test.c:333: PASS: Measured times are within thresholds +tst_timer_test.c:275: INFO: pselect() sleeping for 25000us 50 iterations, threshold 451.29us +tst_timer_test.c:318: INFO: min 25345us, max 25379us, median 25352us, trunc mean 25352.15us (discarded 2) +tst_timer_test.c:333: PASS: Measured times are within thresholds +tst_timer_test.c:275: INFO: pselect() sleeping for 100000us 10 iterations, threshold 537.00us +tst_timer_test.c:318: INFO: min 100397us, max 100414us, median 100406us, trunc mean 100404.56us (discarded 1) +tst_timer_test.c:333: PASS: Measured times are within thresholds +tst_timer_test.c:275: INFO: pselect() sleeping for 1000000us 2 iterations, threshold 4400.00us +tst_timer_test.c:318: INFO: min 1001303us, max 1001414us, median 1001303us, trunc mean 1001303.00us (discarded 1) +tst_timer_test.c:333: PASS: Measured times are within thresholds + +Summary: +passed 7 +failed 0 +skipped 0 +warnings 0 +*** C1361T04: pselect01 PASS (7) +tst_test.c:1072: INFO: Timeout per run is 0h 05m 00s +pselect03.c:43: PASS: pselect() succeeded retval=0 + +Summary: +passed 1 +failed 0 +skipped 0 +warnings 0 +*** C1361T05: pselect03 PASS (1) +bash-4.4$ exit +exit + +Script done on 2020-01-06 07:21:39+00:00 diff --git a/test/issues/1361/C1361_x86_64.txt b/test/issues/1361/C1361_x86_64.txt new file mode 100644 index 00000000..b7398afe --- /dev/null +++ b/test/issues/1361/C1361_x86_64.txt @@ -0,0 +1,83 @@ +Script started on Mon Jan 6 15:24:33 2020 +bash-4.2$ make test +gcc C1361T01.c -o C1361T01 +sh ./C1361.sh +mcstop+release.sh ... done +mcreboot.sh -c 1-7,9-15,17-23,25-31 -m 10G@0,10G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24 ... done +x86_64 +*** C1361T01: PASS +tst_test.c:1072: INFO: Timeout per run is 0h 05m 00s +ppoll01.c:221: INFO: case NORMAL +ppoll01.c:252: PASS: revents=0x0005 +ppoll01.c:258: PASS: ret: 1 +ppoll01.c:221: INFO: case MASK_SIGNAL +ppoll01.c:258: PASS: ret: 0 +ppoll01.c:221: INFO: case TIMEOUT +ppoll01.c:258: PASS: ret: 0 +ppoll01.c:221: INFO: case FD_ALREADY_CLOSED +ppoll01.c:252: PASS: revents=0x0020 +ppoll01.c:258: PASS: ret: 1 +ppoll01.c:221: INFO: case SEND_SIGINT +ppoll01.c:261: PASS: ret: -1, errno: EINTR (4) +ppoll01.c:221: INFO: case SEND_SIGINT_RACE_TEST +ppoll01.c:261: PASS: ret: -1, errno: EINTR (4) +ppoll01.c:221: INFO: case INVALID_NFDS +ppoll01.c:261: PASS: ret: -1, errno: EINVAL (22) +ppoll01.c:221: INFO: case INVALID_FDS +ppoll01.c:261: PASS: ret: -1, errno: EFAULT (14) + +Summary: +passed 10 +failed 0 +skipped 0 +warnings 0 +*** C1361T02: ppoll01 PASS (10) +epoll_pwait01 1 TPASS : epoll_pwait(sigmask) blocked signal +epoll_pwait01 0 TINFO : Child process returned TPASS +epoll_pwait01 2 TPASS : epoll_wait() failed as expected: TEST_ERRNO=EINTR(4): Interrupted system call +epoll_pwait01 0 TINFO : Child process returned TPASS +*** C1361T03: epoll_pwait01 PASS (4) +tst_test.c:1072: INFO: Timeout per run is 0h 05m 00s +tst_timer_test.c:356: INFO: CLOCK_MONOTONIC resolution 1ns +tst_timer_test.c:368: INFO: prctl(PR_GET_TIMERSLACK) = 50us +tst_timer_test.c:275: INFO: pselect() sleeping for 1000us 500 iterations, threshold 450.01us +tst_timer_test.c:318: INFO: min 1065us, max 1079us, median 1066us, trunc mean 1065.64us (discarded 25) +tst_timer_test.c:333: PASS: Measured times are within thresholds +tst_timer_test.c:275: INFO: pselect() sleeping for 2000us 500 iterations, threshold 450.01us +tst_timer_test.c:318: INFO: min 2065us, max 2072us, median 2066us, trunc mean 2065.86us (discarded 25) +tst_timer_test.c:333: PASS: Measured times are within thresholds +tst_timer_test.c:275: INFO: pselect() sleeping for 5000us 300 iterations, threshold 450.04us +tst_timer_test.c:318: INFO: min 5065us, max 5072us, median 5066us, trunc mean 5065.87us (discarded 15) +tst_timer_test.c:333: PASS: Measured times are within thresholds +tst_timer_test.c:275: INFO: pselect() sleeping for 10000us 100 iterations, threshold 450.33us +tst_timer_test.c:318: INFO: min 10065us, max 10074us, median 10066us, trunc mean 10065.57us (discarded 5) +tst_timer_test.c:333: PASS: Measured times are within thresholds +tst_timer_test.c:275: INFO: pselect() sleeping for 25000us 50 iterations, threshold 451.29us +tst_timer_test.c:318: INFO: min 25064us, max 25077us, median 25065us, trunc mean 25065.38us (discarded 2) +tst_timer_test.c:333: PASS: Measured times are within thresholds +tst_timer_test.c:275: INFO: pselect() sleeping for 100000us 10 iterations, threshold 537.00us +tst_timer_test.c:318: INFO: min 100109us, max 100118us, median 100110us, trunc mean 100111.33us (discarded 1) +tst_timer_test.c:333: PASS: Measured times are within thresholds +tst_timer_test.c:275: INFO: pselect() sleeping for 1000000us 2 iterations, threshold 4400.00us +tst_timer_test.c:318: INFO: min 1001000us, max 1001013us, median 1001000us, trunc mean 1001000.00us (discarded 1) +tst_timer_test.c:333: PASS: Measured times are within thresholds + +Summary: +passed 7 +failed 0 +skipped 0 +warnings 0 +*** C1361T04: pselect01 PASS (7) +tst_test.c:1072: INFO: Timeout per run is 0h 05m 00s +pselect03.c:43: PASS: pselect() succeeded retval=0 + +Summary: +passed 1 +failed 0 +skipped 0 +warnings 0 +*** C1361T05: pselect03 PASS (1) +bash-4.2$ exit +exit + +Script done on Mon Jan 6 15:25:00 2020 diff --git a/test/issues/1361/Makefile b/test/issues/1361/Makefile new file mode 100644 index 00000000..dba409aa --- /dev/null +++ b/test/issues/1361/Makefile @@ -0,0 +1,13 @@ +CC = gcc +TARGET = C1361T01 + +all:: $(TARGET) + +C452T01: C1361T01.c + $(CC) -g -Wall -o $@ $^ + +test:: all + sh ./C1361.sh + +clean:: + rm -f $(TARGET) *.o diff --git a/test/issues/1361/README b/test/issues/1361/README new file mode 100644 index 00000000..f1416996 --- /dev/null +++ b/test/issues/1361/README @@ -0,0 +1,23 @@ +【Issue#1361 動作確認】 +□ テスト内容 +1. Issue 指摘事項の再現確認 +C1361T01 pselect のシグナルマスクが機能することを確認する。PASSすること。 +C1361T02 LTP epoll_pwait01 を実行し、PASSすること。 +C1361T03 LTP ppoll01 を実行し、PASSすること。 + +2. LTP を用いて既存処理に影響しないことを確認 + pselect, epoll_pwait, ppoll の処理を変更したので、関連するテストプログラム + を実行し、すべてPASSすること。 +C1361T04 LTP pselect01 を実行し、PASSすること。 +C1361T05 LTP pselect03 を実行し、PASSすること。 + +□ 実行手順 +$ make test + +McKernelのインストール先や LTP の配置場所は、$HOME/.mck_test_config を +参照する。.mck_test_config は、McKernel をビルドした際に生成される +mck_test_config.sample ファイルを $HOME にコピーし、適宜編集すること。 + +□ 実行結果 +C1361_x86_64.txt(x86_64実行結果)、C1361_arm64.txt(arm64実行結果)参照。 +全ての項目が PASS していることを確認。