aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Chagin <dchagin@FreeBSD.org>2021-06-10 11:51:30 +0000
committerDmitry Chagin <dchagin@FreeBSD.org>2022-06-17 19:30:15 +0000
commit2eae70753e443a2b801a3bb9202b2e662dac9df1 (patch)
tree91de5805f5902ca6a2c8f148bd408dd6323992fe
parentf83465c2e765f0bf135f376bf524b01a1ad2bedb (diff)
downloadsrc-2eae70753e443a2b801a3bb9202b2e662dac9df1.tar.gz
src-2eae70753e443a2b801a3bb9202b2e662dac9df1.zip
linux(4): Implement rt_sigtimedwait_time64 system call.
It still does not work as intended, awaits D30675. MFC after: 2 weeks (cherry picked from commit db4a1f331b73eb821d5d9c3cbb478ad50223f023)
-rw-r--r--sys/amd64/linux32/linux32_dummy_machdep.c1
-rw-r--r--sys/amd64/linux32/syscalls.master7
-rw-r--r--sys/compat/linux/linux_signal.c70
-rw-r--r--sys/i386/linux/linux_dummy_machdep.c1
-rw-r--r--sys/i386/linux/syscalls.master7
5 files changed, 64 insertions, 22 deletions
diff --git a/sys/amd64/linux32/linux32_dummy_machdep.c b/sys/amd64/linux32/linux32_dummy_machdep.c
index bfb4ff71e0b1..837496641311 100644
--- a/sys/amd64/linux32/linux32_dummy_machdep.c
+++ b/sys/amd64/linux32/linux32_dummy_machdep.c
@@ -79,5 +79,4 @@ DUMMY(recvmmsg_time64);
DUMMY(mq_timedsend_time64);
DUMMY(mq_timedreceive_time64);
DUMMY(semtimedop_time64);
-DUMMY(rt_sigtimedwait_time64);
DUMMY(sched_rr_get_interval_time64);
diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master
index bf2778bb91fd..92c1c0e53cdc 100644
--- a/sys/amd64/linux32/syscalls.master
+++ b/sys/amd64/linux32/syscalls.master
@@ -2412,7 +2412,12 @@
int linux_semtimedop_time64(void);
}
421 AUE_NULL STD {
- int linux_rt_sigtimedwait_time64(void);
+ int linux_rt_sigtimedwait_time64(
+ l_sigset_t *mask,
+ l_siginfo_t *ptr,
+ struct l_timespec64 *timeout,
+ l_size_t sigsetsize
+ );
}
422 AUE_NULL STD {
int linux_sys_futex_time64(
diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c
index 8c41d724c0b9..610bd7916689 100644
--- a/sys/compat/linux/linux_signal.c
+++ b/sys/compat/linux/linux_signal.c
@@ -60,6 +60,9 @@ __FBSDID("$FreeBSD$");
static int linux_do_tkill(struct thread *td, struct thread *tdt,
ksiginfo_t *ksi);
static void sicode_to_lsicode(int si_code, int *lsi_code);
+static int linux_common_rt_sigtimedwait(struct thread *,
+ l_sigset_t *, struct timespec *, l_siginfo_t *,
+ l_size_t);
static void
linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
@@ -391,29 +394,14 @@ linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args)
return (copyout(&lset, args->set, args->sigsetsize));
}
-/*
- * MPSAFE
- */
int
linux_rt_sigtimedwait(struct thread *td,
struct linux_rt_sigtimedwait_args *args)
{
- int error, sig;
struct timespec ts, *tsa;
struct l_timespec lts;
- l_sigset_t lset;
- sigset_t bset;
- l_siginfo_t lsi;
- ksiginfo_t ksi;
-
- if (args->sigsetsize != sizeof(l_sigset_t))
- return (EINVAL);
-
- if ((error = copyin(args->mask, &lset, sizeof(lset))))
- return (error);
- linux_to_bsd_sigset(&lset, &bset);
+ int error;
- tsa = NULL;
if (args->timeout) {
if ((error = copyin(args->timeout, &lts, sizeof(lts))))
return (error);
@@ -424,16 +412,38 @@ linux_rt_sigtimedwait(struct thread *td,
} else
tsa = NULL;
+ return (linux_common_rt_sigtimedwait(td, args->mask, tsa,
+ args->ptr, args->sigsetsize));
+}
+
+static int
+linux_common_rt_sigtimedwait(struct thread *td, l_sigset_t *mask,
+ struct timespec *tsa, l_siginfo_t *ptr, l_size_t sigsetsize)
+{
+ int error, sig;
+ l_sigset_t lset;
+ sigset_t bset;
+ l_siginfo_t lsi;
+ ksiginfo_t ksi;
+
+ if (sigsetsize != sizeof(l_sigset_t))
+ return (EINVAL);
+
+ if ((error = copyin(mask, &lset, sizeof(lset))))
+ return (error);
+ linux_to_bsd_sigset(&lset, &bset);
+
+ ksiginfo_init(&ksi);
error = kern_sigtimedwait(td, bset, &ksi, tsa);
if (error)
return (error);
sig = bsd_to_linux_signal(ksi.ksi_signo);
- if (args->ptr) {
+ if (ptr) {
memset(&lsi, 0, sizeof(lsi));
siginfo_to_lsiginfo(&ksi.ksi_info, &lsi, sig);
- error = copyout(&lsi, args->ptr, sizeof(lsi));
+ error = copyout(&lsi, ptr, sizeof(lsi));
}
if (error == 0)
td->td_retval[0] = sig;
@@ -441,6 +451,30 @@ linux_rt_sigtimedwait(struct thread *td,
return (error);
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+int
+linux_rt_sigtimedwait_time64(struct thread *td,
+ struct linux_rt_sigtimedwait_time64_args *args)
+{
+ struct timespec ts, *tsa;
+ struct l_timespec64 lts;
+ int error;
+
+ if (args->timeout) {
+ if ((error = copyin(args->timeout, &lts, sizeof(lts))))
+ return (error);
+ error = linux_to_native_timespec64(&ts, &lts);
+ if (error != 0)
+ return (error);
+ tsa = &ts;
+ } else
+ tsa = NULL;
+
+ return (linux_common_rt_sigtimedwait(td, args->mask, tsa,
+ args->ptr, args->sigsetsize));
+}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
+
int
linux_kill(struct thread *td, struct linux_kill_args *args)
{
diff --git a/sys/i386/linux/linux_dummy_machdep.c b/sys/i386/linux/linux_dummy_machdep.c
index 78503b9453ee..a349fab5b637 100644
--- a/sys/i386/linux/linux_dummy_machdep.c
+++ b/sys/i386/linux/linux_dummy_machdep.c
@@ -81,5 +81,4 @@ DUMMY(recvmmsg_time64);
DUMMY(mq_timedsend_time64);
DUMMY(mq_timedreceive_time64);
DUMMY(semtimedop_time64);
-DUMMY(rt_sigtimedwait_time64);
DUMMY(sched_rr_get_interval_time64);
diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master
index d78f000530e3..c42d9af0058d 100644
--- a/sys/i386/linux/syscalls.master
+++ b/sys/i386/linux/syscalls.master
@@ -2430,7 +2430,12 @@
int linux_semtimedop_time64(void);
}
421 AUE_NULL STD {
- int linux_rt_sigtimedwait_time64(void);
+ int linux_rt_sigtimedwait_time64(
+ l_sigset_t *mask,
+ l_siginfo_t *ptr,
+ struct l_timespec64 *timeout,
+ l_size_t sigsetsize
+ );
}
422 AUE_NULL STD {
int linux_sys_futex_time64(