From: Song Chen <chensong_2...@189.cn>

Add a syscall specific for sigtimedwait with 64bit
time_t.

Signed-off-by: Song Chen <chensong_2...@189.cn>
[Florian: Tracing, fix return value EAGAIN vs. ETIMEOUT]
Signed-off-by: Florian Bezdeka <florian.bezd...@siemens.com>
---
 include/cobalt/uapi/syscall.h      |  1 +
 kernel/cobalt/posix/signal.c       | 21 +++++++++++++++++++--
 kernel/cobalt/posix/signal.h       |  5 +++++
 kernel/cobalt/posix/syscall32.c    | 21 +++++++++++++++++++++
 kernel/cobalt/posix/syscall32.h    |  5 +++++
 kernel/cobalt/trace/cobalt-posix.h |  4 ++--
 6 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/include/cobalt/uapi/syscall.h b/include/cobalt/uapi/syscall.h
index c27d6d044..4de7e59d0 100644
--- a/include/cobalt/uapi/syscall.h
+++ b/include/cobalt/uapi/syscall.h
@@ -131,6 +131,7 @@
 #define sc_cobalt_mutex_timedlock64            108
 #define sc_cobalt_mq_timedsend64               109
 #define sc_cobalt_mq_timedreceive64            110
+#define sc_cobalt_sigtimedwait64               111
 
 #define __NR_COBALT_SYSCALLS                   128 /* Power of 2 */
 
diff --git a/kernel/cobalt/posix/signal.c b/kernel/cobalt/posix/signal.c
index 0b43b5fcf..e3ba3abcf 100644
--- a/kernel/cobalt/posix/signal.c
+++ b/kernel/cobalt/posix/signal.c
@@ -18,6 +18,7 @@
 #include <linux/sched.h>
 #include <cobalt/kernel/assert.h>
 #include <cobalt/kernel/compat.h>
+#include <cobalt/kernel/time.h>
 #include "internal.h"
 #include "signal.h"
 #include "thread.h"
@@ -413,9 +414,8 @@ int __cobalt_sigtimedwait(sigset_t *set,
 {
        xnticks_t ticks;
 
-       if ((unsigned long)timeout->tv_nsec >= ONE_BILLION)
+       if (!timespec64_valid(timeout))
                return -EINVAL;
-
        ticks = ts2ns(timeout);
        if (ticks++ == 0)
                ticks = XN_NONBLOCK;
@@ -440,6 +440,23 @@ COBALT_SYSCALL(sigtimedwait, nonrestartable,
        return __cobalt_sigtimedwait(&set, &timeout, u_si, false);
 }
 
+COBALT_SYSCALL(sigtimedwait64, nonrestartable,
+              (const sigset_t __user *u_set,
+               struct siginfo __user *u_si,
+               const struct __kernel_timespec __user *u_timeout))
+{
+       struct timespec64 timeout;
+       sigset_t set;
+
+       if (cobalt_copy_from_user(&set, u_set, sizeof(set)))
+               return -EFAULT;
+
+       if (cobalt_get_timespec64(&timeout, u_timeout))
+               return -EFAULT;
+
+       return __cobalt_sigtimedwait(&set, &timeout, u_si, false);
+}
+
 int __cobalt_sigwaitinfo(sigset_t *set,
                         void __user *u_si,
                         bool compat)
diff --git a/kernel/cobalt/posix/signal.h b/kernel/cobalt/posix/signal.h
index fc26ad065..121db8f9b 100644
--- a/kernel/cobalt/posix/signal.h
+++ b/kernel/cobalt/posix/signal.h
@@ -96,6 +96,11 @@ COBALT_SYSCALL_DECL(sigtimedwait,
                     struct siginfo __user *u_si,
                     const struct __user_old_timespec __user *u_timeout));
 
+COBALT_SYSCALL_DECL(sigtimedwait64,
+                   (const sigset_t __user *u_set,
+                    struct siginfo __user *u_si,
+                    const struct __kernel_timespec __user *u_timeout));
+
 COBALT_SYSCALL_DECL(sigwaitinfo,
                    (const sigset_t __user *u_set,
                     struct siginfo __user *u_si));
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index d52be0207..79fc365fc 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/err.h>
 #include <cobalt/uapi/syscall.h>
+#include <cobalt/kernel/time.h>
 #include <xenomai/rtdm/internal.h>
 #include "internal.h"
 #include "syscall32.h"
@@ -696,6 +697,26 @@ COBALT_SYSCALL32emu(sigtimedwait, nonrestartable,
        return __cobalt_sigtimedwait(&set, &timeout, u_si, true);
 }
 
+COBALT_SYSCALL32emu(sigtimedwait64, nonrestartable,
+                   (const compat_sigset_t __user *u_set,
+                    struct compat_siginfo __user *u_si,
+                    const struct __kernel_timespec __user *u_timeout))
+{
+       struct timespec64 timeout;
+       sigset_t set;
+       int ret;
+
+       ret = sys32_get_sigset(&set, u_set);
+       if (ret)
+               return ret;
+
+       ret = cobalt_get_timespec64(&timeout, u_timeout);
+       if (ret)
+               return ret;
+
+       return __cobalt_sigtimedwait(&set, &timeout, u_si, true);
+}
+
 COBALT_SYSCALL32emu(sigwaitinfo, nonrestartable,
                    (const compat_sigset_t __user *u_set,
                     struct compat_siginfo __user *u_si))
diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h
index 006054e85..cf295ed5e 100644
--- a/kernel/cobalt/posix/syscall32.h
+++ b/kernel/cobalt/posix/syscall32.h
@@ -197,6 +197,11 @@ COBALT_SYSCALL32emu_DECL(sigtimedwait,
                          struct compat_siginfo __user *u_si,
                          const struct old_timespec32 __user *u_timeout));
 
+COBALT_SYSCALL32emu_DECL(sigtimedwait64,
+                        (const compat_sigset_t __user *u_set,
+                         struct compat_siginfo __user *u_si,
+                         const struct __kernel_timespec __user *u_timeout));
+
 COBALT_SYSCALL32emu_DECL(sigwaitinfo,
                         (const compat_sigset_t __user *u_set,
                          struct compat_siginfo __user *u_si));
diff --git a/kernel/cobalt/trace/cobalt-posix.h 
b/kernel/cobalt/trace/cobalt-posix.h
index b046c8a0e..5d14d851f 100644
--- a/kernel/cobalt/trace/cobalt-posix.h
+++ b/kernel/cobalt/trace/cobalt-posix.h
@@ -163,8 +163,8 @@
                __cobalt_symbolic_syscall(clock_adjtime64),             \
                __cobalt_symbolic_syscall(mutex_timedlock64),           \
                __cobalt_symbolic_syscall(mq_timedsend64),              \
-               __cobalt_symbolic_syscall(mq_timedreceive64))
-
+               __cobalt_symbolic_syscall(mq_timedreceive64),           \
+               __cobalt_symbolic_syscall(sigtimedwait64))
 
 DECLARE_EVENT_CLASS(cobalt_syscall_entry,
        TP_PROTO(unsigned int nr),
-- 
2.30.2


Reply via email to