Adding monitor_wait64. Patch is based on v1 sent out by Song and was
re-worked to apply on top of current next/master.

__cobalt_monitor_wait() is now validating the struct timespec64 it
received from userland. That was not the case up to now.

Signed-off-by: Florian Bezdeka <florian.bezd...@siemens.com>
---
 include/cobalt/uapi/syscall.h      |  1 +
 kernel/cobalt/posix/monitor.c      | 32 +++++++++++++++++++++++++++++-
 kernel/cobalt/posix/monitor.h      | 10 ++++++++++
 kernel/cobalt/posix/syscall32.c    |  8 ++++++++
 kernel/cobalt/posix/syscall32.h    |  6 ++++++
 kernel/cobalt/trace/cobalt-posix.h |  3 ++-
 6 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/include/cobalt/uapi/syscall.h b/include/cobalt/uapi/syscall.h
index 4de7e59d0..e49110f5d 100644
--- a/include/cobalt/uapi/syscall.h
+++ b/include/cobalt/uapi/syscall.h
@@ -132,6 +132,7 @@
 #define sc_cobalt_mq_timedsend64               109
 #define sc_cobalt_mq_timedreceive64            110
 #define sc_cobalt_sigtimedwait64               111
+#define sc_cobalt_monitor_wait64               112
 
 #define __NR_COBALT_SYSCALLS                   128 /* Power of 2 */
 
diff --git a/kernel/cobalt/posix/monitor.c b/kernel/cobalt/posix/monitor.c
index b907e0050..0d0213273 100644
--- a/kernel/cobalt/posix/monitor.c
+++ b/kernel/cobalt/posix/monitor.c
@@ -20,6 +20,7 @@
 #include "clock.h"
 #include "monitor.h"
 #include <trace/events/cobalt-posix.h>
+#include <cobalt/kernel/time.h>
 
 /*
  * The Cobalt monitor is a double-wait condition object, serializing
@@ -218,8 +219,12 @@ int __cobalt_monitor_wait(struct cobalt_monitor_shadow 
__user *u_mon,
 
        handle = cobalt_get_handle_from_user(&u_mon->handle);
 
-       if (ts)
+       if (ts) {
+               if (!timespec64_valid(ts))
+                       return -EINVAL;
+
                timeout = ts2ns(ts) + 1;
+       }
 
        xnlock_get_irqsave(&nklock, s);
 
@@ -289,6 +294,24 @@ out:
        return ret;
 }
 
+int __cobalt_monitor_wait64(struct cobalt_monitor_shadow __user *u_mon,
+                           int event,
+                           const struct __kernel_timespec __user *u_ts,
+                           int __user *u_ret)
+{
+       struct timespec64 ts, *tsp = NULL;
+       int ret;
+
+       if (u_ts) {
+               tsp = &ts;
+               ret = cobalt_get_timespec64(&ts, u_ts);
+               if (ret)
+                       return ret;
+       }
+
+       return __cobalt_monitor_wait(u_mon, event, tsp, u_ret);
+}
+
 COBALT_SYSCALL(monitor_wait, nonrestartable,
               (struct cobalt_monitor_shadow __user *u_mon,
               int event, const struct __user_old_timespec __user *u_ts,
@@ -307,6 +330,13 @@ COBALT_SYSCALL(monitor_wait, nonrestartable,
        return __cobalt_monitor_wait(u_mon, event, tsp, u_ret);
 }
 
+COBALT_SYSCALL(monitor_wait64, nonrestartable,
+              (struct cobalt_monitor_shadow __user *u_mon, int event,
+               const struct __kernel_timespec __user *u_ts, int __user *u_ret))
+{
+       return __cobalt_monitor_wait64(u_mon, event, u_ts, u_ret);
+}
+
 COBALT_SYSCALL(monitor_sync, nonrestartable,
               (struct cobalt_monitor_shadow __user *u_mon))
 {
diff --git a/kernel/cobalt/posix/monitor.h b/kernel/cobalt/posix/monitor.h
index d4a4aa24e..bf8794e36 100644
--- a/kernel/cobalt/posix/monitor.h
+++ b/kernel/cobalt/posix/monitor.h
@@ -42,6 +42,11 @@ int __cobalt_monitor_wait(struct cobalt_monitor_shadow 
__user *u_mon,
                          int event, const struct timespec64 *ts,
                          int __user *u_ret);
 
+int __cobalt_monitor_wait64(struct cobalt_monitor_shadow __user *u_mon,
+                           int event,
+                           const struct __kernel_timespec __user *u_ts,
+                           int __user *u_ret);
+
 COBALT_SYSCALL_DECL(monitor_init,
                    (struct cobalt_monitor_shadow __user *u_monsh,
                     clockid_t clk_id,
@@ -61,6 +66,11 @@ COBALT_SYSCALL_DECL(monitor_wait,
                     int event, const struct __user_old_timespec __user *u_ts,
                     int __user *u_ret));
 
+COBALT_SYSCALL_DECL(monitor_wait64,
+                   (struct cobalt_monitor_shadow __user *u_monsh, int event,
+                    const struct __kernel_timespec __user *u_ts,
+                    int __user *u_ret));
+
 COBALT_SYSCALL_DECL(monitor_destroy,
                    (struct cobalt_monitor_shadow __user *u_monsh));
 
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index 79fc365fc..e6c9831b9 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -768,6 +768,14 @@ COBALT_SYSCALL32emu(monitor_wait, nonrestartable,
        return __cobalt_monitor_wait(u_mon, event, tsp, u_ret);
 }
 
+COBALT_SYSCALL32emu(monitor_wait64, nonrestartable,
+                   (struct cobalt_monitor_shadow __user *u_mon, int event,
+                    const struct __kernel_timespec __user *u_ts,
+                    int __user *u_ret))
+{
+       return __cobalt_monitor_wait64(u_mon, event, u_ts, u_ret);
+}
+
 COBALT_SYSCALL32emu(event_wait, primary,
                    (struct cobalt_event_shadow __user *u_event,
                     unsigned int bits,
diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h
index cf295ed5e..a2ef67808 100644
--- a/kernel/cobalt/posix/syscall32.h
+++ b/kernel/cobalt/posix/syscall32.h
@@ -218,6 +218,12 @@ COBALT_SYSCALL32emu_DECL(monitor_wait,
                          int event, const struct old_timespec32 __user *u_ts,
                          int __user *u_ret));
 
+COBALT_SYSCALL32emu_DECL(monitor_wait64,
+                        (struct cobalt_monitor_shadow __user *u_mon,
+                         int event,
+                         const struct __kernel_timespec __user *u_ts,
+                         int __user *u_ret));
+
 COBALT_SYSCALL32emu_DECL(event_wait,
                         (struct cobalt_event_shadow __user *u_event,
                          unsigned int bits,
diff --git a/kernel/cobalt/trace/cobalt-posix.h 
b/kernel/cobalt/trace/cobalt-posix.h
index 5d14d851f..221e25037 100644
--- a/kernel/cobalt/trace/cobalt-posix.h
+++ b/kernel/cobalt/trace/cobalt-posix.h
@@ -164,7 +164,8 @@
                __cobalt_symbolic_syscall(mutex_timedlock64),           \
                __cobalt_symbolic_syscall(mq_timedsend64),              \
                __cobalt_symbolic_syscall(mq_timedreceive64),           \
-               __cobalt_symbolic_syscall(sigtimedwait64))
+               __cobalt_symbolic_syscall(sigtimedwait64),              \
+               __cobalt_symbolic_syscall(monitor_wait64))
 
 DECLARE_EVENT_CLASS(cobalt_syscall_entry,
        TP_PROTO(unsigned int nr),
-- 
2.30.2


Reply via email to