* [PATCH v5 1/3] y2038: cobalt/posix/io: Adding recvmmsg64
2021-10-06 13:54 [PATCH v5 0/3] y2038: Adding recvmmsg64 Florian Bezdeka
@ 2021-10-06 13:54 ` Florian Bezdeka
2021-10-06 15:27 ` Jan Kiszka
2021-10-06 13:54 ` [PATCH v5 2/3] y2038: lib/cobalt/rtdm: dispatch recvmmg Florian Bezdeka
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Florian Bezdeka @ 2021-10-06 13:54 UTC (permalink / raw)
To: xenomai
From: Song Chen <chensong_2000@189.cn>
Add a syscall specific for recvmmsg64 with 64bit time_t.
Signed-off-by: Song Chen <chensong_2000@189.cn>
[Florian: Fixed some style issues]
[Florian: Added Song's Signed-off back (malformed patch received)]
[Florian: Fixed tracing infrastructure]
Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
include/cobalt/kernel/rtdm/fd.h | 5 +++++
include/cobalt/uapi/syscall.h | 1 +
kernel/cobalt/posix/io.c | 9 +++++++++
kernel/cobalt/posix/io.h | 5 +++++
kernel/cobalt/posix/syscall32.c | 9 +++++++++
kernel/cobalt/posix/syscall32.h | 6 ++++++
kernel/cobalt/rtdm/fd.c | 21 ++++++++++++++++++++-
kernel/cobalt/trace/cobalt-posix.h | 3 ++-
8 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/include/cobalt/kernel/rtdm/fd.h b/include/cobalt/kernel/rtdm/fd.h
index 37a09c43e..058a9c638 100644
--- a/include/cobalt/kernel/rtdm/fd.h
+++ b/include/cobalt/kernel/rtdm/fd.h
@@ -382,6 +382,11 @@ int __rtdm_fd_recvmmsg(int ufd, void __user *u_msgvec, unsigned int vlen,
int (*put_mmsg)(void __user **u_mmsg_p, const struct mmsghdr *mmsg),
int (*get_timespec)(struct timespec64 *ts, const void __user *u_ts));
+int __rtdm_fd_recvmmsg64(int ufd, void __user *u_msgvec, unsigned int vlen,
+ unsigned int flags, void __user *u_timeout,
+ int (*get_mmsg)(struct mmsghdr *mmsg, void __user *u_mmsg),
+ int (*put_mmsg)(void __user **u_mmsg_p, const struct mmsghdr *mmsg));
+
ssize_t rtdm_fd_sendmsg(int ufd, const struct user_msghdr *msg,
int flags);
diff --git a/include/cobalt/uapi/syscall.h b/include/cobalt/uapi/syscall.h
index 16edce15d..1523ddd2d 100644
--- a/include/cobalt/uapi/syscall.h
+++ b/include/cobalt/uapi/syscall.h
@@ -134,6 +134,7 @@
#define sc_cobalt_sigtimedwait64 111
#define sc_cobalt_monitor_wait64 112
#define sc_cobalt_event_wait64 113
+#define sc_cobalt_recvmmsg64 114
#define __NR_COBALT_SYSCALLS 128 /* Power of 2 */
diff --git a/kernel/cobalt/posix/io.c b/kernel/cobalt/posix/io.c
index 0c17f55bf..0f9c963ad 100644
--- a/kernel/cobalt/posix/io.c
+++ b/kernel/cobalt/posix/io.c
@@ -26,6 +26,7 @@
#include "internal.h"
#include "clock.h"
#include "io.h"
+#include <cobalt/kernel/time.h>
COBALT_SYSCALL(open, lostage,
(const char __user *u_path, int oflag))
@@ -121,6 +122,14 @@ COBALT_SYSCALL(recvmmsg, primary,
get_mmsg, put_mmsg, get_timespec);
}
+COBALT_SYSCALL(recvmmsg64, primary,
+ (int fd, struct mmsghdr __user *u_msgvec, unsigned int vlen,
+ unsigned int flags, struct __kernel_timespec __user *u_timeout))
+{
+ return __rtdm_fd_recvmmsg64(fd, u_msgvec, vlen, flags, u_timeout,
+ get_mmsg, put_mmsg);
+}
+
COBALT_SYSCALL(sendmsg, handover,
(int fd, struct user_msghdr __user *umsg, int flags))
{
diff --git a/kernel/cobalt/posix/io.h b/kernel/cobalt/posix/io.h
index d9f29fa59..842db084e 100644
--- a/kernel/cobalt/posix/io.h
+++ b/kernel/cobalt/posix/io.h
@@ -58,6 +58,11 @@ COBALT_SYSCALL_DECL(recvmmsg,
(int fd, struct mmsghdr __user *u_msgvec, unsigned int vlen,
unsigned int flags, struct __user_old_timespec __user *u_timeout));
+COBALT_SYSCALL_DECL(recvmmsg64,
+ (int fd, struct mmsghdr __user *u_msgvec, unsigned int vlen,
+ unsigned int flags,
+ struct __kernel_timespec __user *u_timeout));
+
COBALT_SYSCALL_DECL(sendmsg,
(int fd, struct user_msghdr __user *umsg, int flags));
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index 2d88fac83..b0b2785e0 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -860,6 +860,15 @@ COBALT_SYSCALL32emu(recvmmsg, primary,
get_timespec32);
}
+COBALT_SYSCALL32emu(recvmmsg64, primary,
+ (int ufd, struct compat_mmsghdr __user *u_msgvec,
+ unsigned int vlen, unsigned int flags,
+ struct __kernel_timespec *u_timeout))
+{
+ return __rtdm_fd_recvmmsg64(ufd, u_msgvec, vlen, flags, u_timeout,
+ get_mmsg32, put_mmsg32);
+}
+
COBALT_SYSCALL32emu(sendmsg, handover,
(int fd, struct compat_msghdr __user *umsg, int flags))
{
diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h
index 3eb66571b..72e32f4f8 100644
--- a/kernel/cobalt/posix/syscall32.h
+++ b/kernel/cobalt/posix/syscall32.h
@@ -253,6 +253,12 @@ COBALT_SYSCALL32emu_DECL(recvmmsg,
unsigned int vlen,
unsigned int flags, struct old_timespec32 *u_timeout));
+COBALT_SYSCALL32emu_DECL(recvmmsg64,
+ (int fd, struct compat_mmsghdr __user *u_msgvec,
+ unsigned int vlen,
+ unsigned int flags,
+ struct __kernel_timespec *u_timeout));
+
COBALT_SYSCALL32emu_DECL(sendmsg,
(int fd, struct compat_msghdr __user *umsg,
int flags));
diff --git a/kernel/cobalt/rtdm/fd.c b/kernel/cobalt/rtdm/fd.c
index 8e4e15e79..c314d9f65 100644
--- a/kernel/cobalt/rtdm/fd.c
+++ b/kernel/cobalt/rtdm/fd.c
@@ -28,6 +28,7 @@
#include <cobalt/kernel/registry.h>
#include <cobalt/kernel/lock.h>
#include <cobalt/kernel/ppd.h>
+#include <cobalt/kernel/time.h>
#include <pipeline/inband_work.h>
#include <trace/events/cobalt-rtdm.h>
#include <rtdm/fd.h>
@@ -689,7 +690,7 @@ int __rtdm_fd_recvmmsg(int ufd, void __user *u_msgvec, unsigned int vlen,
if (ret)
goto fail;
- if ((unsigned long)ts.tv_nsec >= ONE_BILLION) {
+ if (!timespec64_valid(&ts)) {
ret = -EINVAL;
goto fail;
}
@@ -753,6 +754,24 @@ out:
return ret;
}
+static inline int __rtdm_fetch_timeout64(struct timespec64 *ts,
+ const void __user *u_ts)
+{
+ return u_ts == NULL ? -EFAULT : cobalt_get_timespec64(ts, u_ts);
+}
+
+int __rtdm_fd_recvmmsg64(int ufd, void __user *u_msgvec, unsigned int vlen,
+ unsigned int flags, void __user *u_timeout,
+ int (*get_mmsg)(struct mmsghdr *mmsg,
+ void __user *u_mmsg),
+ int (*put_mmsg)(void __user **u_mmsg_p,
+ const struct mmsghdr *mmsg))
+{
+ return __rtdm_fd_recvmmsg(ufd, u_msgvec, vlen, flags, u_timeout,
+ get_mmsg, put_mmsg, __rtdm_fetch_timeout64);
+}
+
+
ssize_t rtdm_fd_sendmsg(int ufd, const struct user_msghdr *msg, int flags)
{
struct rtdm_fd *fd;
diff --git a/kernel/cobalt/trace/cobalt-posix.h b/kernel/cobalt/trace/cobalt-posix.h
index 45e3cbcf7..2bc004dab 100644
--- a/kernel/cobalt/trace/cobalt-posix.h
+++ b/kernel/cobalt/trace/cobalt-posix.h
@@ -166,7 +166,8 @@
__cobalt_symbolic_syscall(mq_timedreceive64), \
__cobalt_symbolic_syscall(sigtimedwait64), \
__cobalt_symbolic_syscall(monitor_wait64), \
- __cobalt_symbolic_syscall(event_wait64))
+ __cobalt_symbolic_syscall(event_wait64), \
+ __cobalt_symbolic_syscall(recvmmsg64))
DECLARE_EVENT_CLASS(cobalt_syscall_entry,
TP_PROTO(unsigned int nr),
--
2.31.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v5 3/3] y2038: testsuite/smokey/y2038: testcase for recvmmsg64
2021-10-06 13:54 [PATCH v5 0/3] y2038: Adding recvmmsg64 Florian Bezdeka
2021-10-06 13:54 ` [PATCH v5 1/3] y2038: cobalt/posix/io: " Florian Bezdeka
2021-10-06 13:54 ` [PATCH v5 2/3] y2038: lib/cobalt/rtdm: dispatch recvmmg Florian Bezdeka
@ 2021-10-06 13:54 ` Florian Bezdeka
2021-10-06 15:31 ` [PATCH v5 0/3] y2038: Adding recvmmsg64 Jan Kiszka
3 siblings, 0 replies; 6+ messages in thread
From: Florian Bezdeka @ 2021-10-06 13:54 UTC (permalink / raw)
To: xenomai
From: Song Chen <chensong_2000@189.cn>
Extending the test suite for recvmmsg64 test.
Signed-off-by: Song Chen <chensong_2000@189.cn>
[Florian: Rebased the patch on top of next]
[Florian: switched to CLOCK_MONOTONIC]
[Florian: Fixed error handling of the socket() call]
Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
testsuite/smokey/y2038/syscall-tests.c | 127 +++++++++++++++++++++++++
1 file changed, 127 insertions(+)
diff --git a/testsuite/smokey/y2038/syscall-tests.c b/testsuite/smokey/y2038/syscall-tests.c
index 5104b87fa..f025fd55d 100644
--- a/testsuite/smokey/y2038/syscall-tests.c
+++ b/testsuite/smokey/y2038/syscall-tests.c
@@ -13,6 +13,7 @@
#include <smokey/smokey.h>
#include <sys/utsname.h>
#include <mqueue.h>
+#include <rtdm/ipc.h>
smokey_test_plugin(y2038, SMOKEY_NOARGS, "Validate correct y2038 support");
@@ -990,6 +991,128 @@ static int test_sc_cobalt_event_wait64(void)
return 0;
}
+static int test_sc_cobalt_recvmmsg64(void)
+{
+ int ret = 0;
+ int sock;
+ int sc_nr = sc_cobalt_recvmmsg64;
+ long data;
+ struct xn_timespec64 t1, t2;
+ struct timespec ts_nat;
+ struct rtipc_port_label plabel;
+ struct sockaddr_ipc saddr;
+
+ struct iovec iov = {
+ .iov_base = &data,
+ .iov_len = sizeof(data),
+ };
+ struct msghdr msg = {
+ .msg_name = NULL,
+ .msg_namelen = 0,
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = NULL,
+ .msg_controllen = 0,
+ };
+
+ sock = smokey_check_errno(socket(AF_RTIPC, SOCK_DGRAM, IPCPROTO_XDDP));
+ if (sock < 0)
+ return sock;
+
+ strcpy(plabel.label, "y2038:recvmmsg64");
+ ret = smokey_check_errno(setsockopt(sock, SOL_XDDP, XDDP_LABEL, &plabel,
+ sizeof(plabel)));
+ if (ret)
+ goto out;
+
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sipc_family = AF_RTIPC;
+ saddr.sipc_port = -1;
+ ret = smokey_check_errno(bind(sock, (struct sockaddr *)&saddr,
+ sizeof(saddr)));
+ if (ret)
+ goto out;
+
+ /* Make sure we don't crash because of NULL pointers */
+ ret = XENOMAI_SYSCALL5(sc_nr, NULL, NULL, NULL, NULL, NULL);
+ if (ret == -ENOSYS) {
+ smokey_note("recvmmsg64: skipped. (no kernel support)");
+ goto out; // Not implemented, nothing to test, success
+ }
+ if (!smokey_assert(ret == -EADV)) {
+ ret = ret ? ret : -EINVAL;
+ goto out;
+ }
+
+ /* Providing an invalid address has to deliver EFAULT */
+ ret = XENOMAI_SYSCALL5(sc_nr, sock, &msg, sizeof(msg), 0,
+ (void *)0xdeadbeefUL);
+ if (!smokey_assert(ret == -EFAULT)) {
+ ret = ret ? ret : -EINVAL;
+ goto out;
+ }
+
+ /*
+ * providing an invalid timeout has to deliver EINVAL
+ */
+ t1.tv_sec = -1;
+ ret = XENOMAI_SYSCALL5(sc_nr, sock, &msg, sizeof(msg), 0, &t1);
+ if (!smokey_assert(ret == -EINVAL)) {
+ ret = ret ? ret : -EINVAL;
+ goto out;
+ }
+
+ /*
+ * providing a zero timeout,
+ * should come back immediately with EWOULDBLOCK
+ */
+ t1.tv_sec = 0;
+ t1.tv_nsec = 0;
+ ret = XENOMAI_SYSCALL5(sc_nr, sock, &msg, sizeof(msg), 0, &t1);
+ if (!smokey_assert(ret == -EWOULDBLOCK)) {
+ ret = ret ? ret : -EINVAL;
+ goto out;
+ }
+
+ /*
+ * Providing a valid timeout, waiting for it to time out and check
+ * that we didn't come back to early.
+ */
+ ret = smokey_check_errno(clock_gettime(CLOCK_MONOTONIC, &ts_nat));
+ if (ret)
+ goto out;
+
+ t1.tv_sec = 0;
+ t1.tv_nsec = 500000;
+
+ ret = XENOMAI_SYSCALL5(sc_nr, sock, &msg, sizeof(msg), 0, &t1);
+ if (!smokey_assert(ret == -ETIMEDOUT)) {
+ ret = ret ? ret : -EINVAL;
+ goto out;
+ }
+
+ t1.tv_sec = ts_nat.tv_sec;
+ t1.tv_nsec = ts_nat.tv_nsec;
+
+ ret = smokey_check_errno(clock_gettime(CLOCK_MONOTONIC, &ts_nat));
+ if (ret)
+ goto out;
+
+ t2.tv_sec = ts_nat.tv_sec;
+ t2.tv_nsec = ts_nat.tv_nsec;
+
+ if (ts_less(&t2, &t1))
+ smokey_warning("recvmmsg64 returned to early!\n"
+ "Expected wakeup at: %lld sec %lld nsec\n"
+ "Back at : %lld sec %lld nsec\n",
+ t1.tv_sec, t1.tv_nsec, t2.tv_sec, t2.tv_nsec);
+
+out:
+ close(sock);
+ return ret;
+}
+
+
static int check_kernel_version(void)
{
int ret, major, minor;
@@ -1068,5 +1191,9 @@ static int run_y2038(struct smokey_test *t, int argc, char *const argv[])
if (ret)
return ret;
+ ret = test_sc_cobalt_recvmmsg64();
+ if (ret)
+ return ret;
+
return 0;
}
--
2.31.1
^ permalink raw reply related [flat|nested] 6+ messages in thread