aboutsummaryrefslogtreecommitdiff
path: root/sys/compat
diff options
context:
space:
mode:
authorDmitry Chagin <dchagin@FreeBSD.org>2022-05-06 17:02:59 +0000
committerDmitry Chagin <dchagin@FreeBSD.org>2022-05-06 17:02:59 +0000
commit3245a2ecea21ace3d97cec1266fbe29c88ba1a59 (patch)
treea92a298be90b1c824c5508d0a2e562d05f1fda2f /sys/compat
parent430460d7178285a26087d294177627e6c88ad369 (diff)
downloadsrc-3245a2ecea21ace3d97cec1266fbe29c88ba1a59.tar.gz
src-3245a2ecea21ace3d97cec1266fbe29c88ba1a59.zip
linux(4): Implement semtimedop syscalls.
On i386 are two semtimedop. The old one is called via multiplexor and uses 32-bit timespec, and new semtimedop_tim64, which is uses 64-bit timespec. MFC after: 2 weeks
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/linux/linux_ipc.c45
-rw-r--r--sys/compat/linux/linux_ipc.h13
2 files changed, 58 insertions, 0 deletions
diff --git a/sys/compat/linux/linux_ipc.c b/sys/compat/linux/linux_ipc.c
index 3e810c303a2c..51bf18dcd097 100644
--- a/sys/compat/linux/linux_ipc.c
+++ b/sys/compat/linux/linux_ipc.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <compat/linux/linux_ipc.h>
#include <compat/linux/linux_ipc64.h>
+#include <compat/linux/linux_timer.h>
#include <compat/linux/linux_util.h>
/*
@@ -504,6 +505,50 @@ linux_shminfo_pushdown(l_int ver, struct l_shminfo64 *linux_shminfo64,
}
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+int
+linux_semtimedop_time64(struct thread *td, struct linux_semtimedop_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 (kern_semop(td, args->semid, PTRIN(args->tsops),
+ args->nsops, tsa));
+}
+#endif /* __i386__) || (__amd64__ && COMPAT_LINUX32) */
+
+int
+linux_semtimedop(struct thread *td, struct linux_semtimedop_args *args)
+{
+ struct timespec ts, *tsa;
+ struct l_timespec lts;
+ int error;
+
+ if (args->timeout) {
+ if ((error = copyin(args->timeout, &lts, sizeof(lts))))
+ return (error);
+ error = linux_to_native_timespec(&ts, &lts);
+ if (error != 0)
+ return (error);
+ tsa = &ts;
+ } else
+ tsa = NULL;
+
+ return (kern_semop(td, args->semid, PTRIN(args->tsops),
+ args->nsops, tsa));
+}
+
int
linux_semget(struct thread *td, struct linux_semget_args *args)
{
diff --git a/sys/compat/linux/linux_ipc.h b/sys/compat/linux/linux_ipc.h
index beef18a09507..a148814b8273 100644
--- a/sys/compat/linux/linux_ipc.h
+++ b/sys/compat/linux/linux_ipc.h
@@ -37,6 +37,7 @@
#define LINUX_SEMOP 1
#define LINUX_SEMGET 2
#define LINUX_SEMCTL 3
+#define LINUX_SEMTIMEDOP 4
#define LINUX_MSGSND 11
#define LINUX_MSGRCV 12
#define LINUX_MSGGET 13
@@ -82,4 +83,16 @@
#define LINUX_IPC_64 0x0100 /* New version (support 32-bit UIDs, bigger
message sizes, etc. */
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+struct linux_semtimedop_args
+{
+ l_int semid;
+ struct sembuf *tsops;
+ l_uint nsops;
+ struct l_timespec *timeout;
+};
+
+int linux_semtimedop(struct thread *, struct linux_semtimedop_args *);
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
+
#endif /* _LINUX_IPC_H_ */