Add a syscall specific for mq_timedsend with 64bit
time_t.
Signed-off-by: Song Chen <[email protected]>
---
include/cobalt/uapi/syscall.h | 1 +
kernel/cobalt/posix/mqueue.c | 23 ++++++++++++++++++++++-
kernel/cobalt/posix/mqueue.h | 8 ++++++++
kernel/cobalt/posix/syscall32.c | 8 ++++++++
kernel/cobalt/posix/syscall32.h | 5 +++++
5 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/include/cobalt/uapi/syscall.h b/include/cobalt/uapi/syscall.h
index 6fe57c7..464e170 100644
--- a/include/cobalt/uapi/syscall.h
+++ b/include/cobalt/uapi/syscall.h
@@ -129,6 +129,7 @@
#define sc_cobalt_clock_getres64 106
#define sc_cobalt_clock_adjtime64 107
#define sc_cobalt_mutex_timedlock64 108
+#define sc_cobalt_mq_timedsend64 109
#define __NR_COBALT_SYSCALLS 128 /* Power of 2 */
diff --git a/kernel/cobalt/posix/mqueue.c b/kernel/cobalt/posix/mqueue.c
index dd8acd5..9179427 100644
--- a/kernel/cobalt/posix/mqueue.c
+++ b/kernel/cobalt/posix/mqueue.c
@@ -29,6 +29,7 @@
#include "mqueue.h"
#include "clock.h"
#include <trace/events/cobalt-posix.h>
+#include <cobalt/kernel/time.h>
#define COBALT_MSGMAX 65536
#define COBALT_MSGSIZEMAX (16*1024*1024)
@@ -499,7 +500,7 @@ redo:
ret = fetch_timeout(&ts, u_ts);
if (ret)
return ERR_PTR(ret);
- if ((unsigned long)ts.tv_nsec >= ONE_BILLION)
+ if (!timespec64_valid(&ts))
return ERR_PTR(-EINVAL);
to = ts2ns(&ts) + 1;
tmode = XN_REALTIME;
@@ -941,6 +942,26 @@ COBALT_SYSCALL(mq_timedsend, primary,
u_ts, u_ts ? mq_fetch_timeout : NULL);
}
+static inline int mq_fetch_timeout64(struct timespec64 *ts,
+ const void __user *u_ts)
+{
+ return u_ts == NULL ? -EFAULT : cobalt_get_timespec64(ts, u_ts);
+}
+
+int __cobalt_mq_timedsend64(mqd_t uqd, const void __user *u_buf, size_t len,
+ unsigned int prio, const void __user *u_ts)
+{
+ return __cobalt_mq_timedsend(uqd, u_buf, len, prio,
+ u_ts, u_ts ? mq_fetch_timeout64 : NULL);
+}
+
+COBALT_SYSCALL(mq_timedsend64, primary,
+ (mqd_t uqd, const void __user *u_buf, size_t len,
+ unsigned int prio, const struct __kernel_timespec __user *u_ts))
+{
+ return __cobalt_mq_timedsend64(uqd, u_buf, len, prio, u_ts);
+}
+
int __cobalt_mq_timedreceive(mqd_t uqd, void __user *u_buf,
ssize_t *lenp,
unsigned int __user *u_prio,
diff --git a/kernel/cobalt/posix/mqueue.h b/kernel/cobalt/posix/mqueue.h
index d332202..f8414f4 100644
--- a/kernel/cobalt/posix/mqueue.h
+++ b/kernel/cobalt/posix/mqueue.h
@@ -40,6 +40,9 @@ int __cobalt_mq_timedsend(mqd_t uqd, const void __user
*u_buf, size_t len,
int (*fetch_timeout)(struct timespec64 *ts,
const void __user *u_ts));
+int __cobalt_mq_timedsend64(mqd_t uqd, const void __user *u_buf, size_t len,
+ unsigned int prio, const void __user *u_ts);
+
int __cobalt_mq_timedreceive(mqd_t uqd, void __user *u_buf,
ssize_t *lenp,
unsigned int __user *u_prio,
@@ -63,6 +66,11 @@ COBALT_SYSCALL_DECL(mq_timedsend,
(mqd_t uqd, const void __user *u_buf, size_t len,
unsigned int prio, const struct __user_old_timespec __user
*u_ts));
+COBALT_SYSCALL_DECL(mq_timedsend64,
+ (mqd_t uqd, const void __user *u_buf, size_t len,
+ unsigned int prio,
+ const struct __kernel_timespec __user *u_ts));
+
COBALT_SYSCALL_DECL(mq_timedreceive,
(mqd_t uqd, void __user *u_buf, ssize_t __user *u_len,
unsigned int __user *u_prio,
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index 65dbd55..716fc16 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -324,6 +324,14 @@ COBALT_SYSCALL32emu(mq_timedsend, primary,
u_ts, u_ts ? sys32_fetch_timeout : NULL);
}
+COBALT_SYSCALL32emu(mq_timedsend64, primary,
+ (mqd_t uqd, const void __user *u_buf, size_t len,
+ unsigned int prio,
+ const struct __kernel_timespec __user *u_ts))
+{
+ return __cobalt_mq_timedsend64(uqd, u_buf, len, prio, u_ts);
+}
+
COBALT_SYSCALL32emu(mq_timedreceive, primary,
(mqd_t uqd, void __user *u_buf,
compat_ssize_t __user *u_len,
diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h
index d464d96..dd0e43d 100644
--- a/kernel/cobalt/posix/syscall32.h
+++ b/kernel/cobalt/posix/syscall32.h
@@ -121,6 +121,11 @@ COBALT_SYSCALL32emu_DECL(mq_timedsend,
unsigned int prio,
const struct old_timespec32 __user *u_ts));
+COBALT_SYSCALL32emu(mq_timedsend64, primary,
+ (mqd_t uqd, const void __user *u_buf, size_t len,
+ unsigned int prio,
+ const struct __kernel_timespec __user *u_ts));
+
COBALT_SYSCALL32emu_DECL(mq_timedreceive,
(mqd_t uqd, void __user *u_buf,
compat_ssize_t __user *u_len,
--
2.7.4