mirror of
https://git.FreeBSD.org/src.git
synced 2026-06-02 11:24:32 +00:00
ntsync(4)
The driver implements the ntsync interface as specified in the Linux 7.0-rc3 document Documentation/userspace-api/ntsync.rst. Only the documentation and the userspace tests (Linux' tools/testing/selftests/drivers/ntsync/ntsync.c) were used for reference. When the documentation contradicted the tests, tests behavior was implemented. One quirk is that Linux API needs to return an error from ioctl() and to copyout the modified ioctl() argument. Our generic ioctl() is not flexible enough to implement this, so the ntsync_ioctl_copyout() hack allows to copyout the ioctl parameter directly from the ioctl method, instead of relying on the ioctl infra. The FreeBSD port of the tests, that can be compiled both on FreeBSD and Linux, is available at https://github.com/kostikbel/freebsd-ntsync-test. The Linux binary compiled with the Linux test harness, cannot be run under linuxolator due to unimplemented syscalls, but the shims in freebsd-ntsync-test can be compiled on Linux and resulting Linux/glibc binary run on linuxolator to test linux compat. Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D57038
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright 2026 The FreeBSD Foundation
|
||||
*
|
||||
* This software was developed by Konstantin Belousov <kib@FreeBSD.org>
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __DEV_NTSYNC_H__
|
||||
#define __DEV_NTSYNC_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
struct ntsync_sem_args {
|
||||
uint32_t count;
|
||||
uint32_t max;
|
||||
};
|
||||
|
||||
struct ntsync_mutex_args {
|
||||
uint32_t owner;
|
||||
uint32_t count;
|
||||
};
|
||||
|
||||
struct ntsync_event_args {
|
||||
uint32_t manual;
|
||||
uint32_t signaled;
|
||||
};
|
||||
|
||||
struct ntsync_wait_args {
|
||||
uint64_t timeout;
|
||||
uint64_t objs;
|
||||
uint32_t count;
|
||||
uint32_t index;
|
||||
uint32_t flags;
|
||||
uint32_t owner;
|
||||
uint32_t alert;
|
||||
uint32_t pad;
|
||||
};
|
||||
|
||||
#define NTSYNC_WAIT_REALTIME 0x00000001
|
||||
|
||||
#define NTSYNC_MAX_WAIT_COUNT 64
|
||||
|
||||
/*
|
||||
* 'sp' means that the ioctl is special, it might return both error
|
||||
* and copy out parameters. See ntsync_ioctl_copyout().
|
||||
*/
|
||||
|
||||
#define NTSYNC_IOC_CREATE_SEM _IOW('n', 1, struct ntsync_sem_args)
|
||||
#define NTSYNC_IOC_CREATE_MUTEX _IOW('n', 2, struct ntsync_mutex_args)
|
||||
#define NTSYNC_IOC_CREATE_EVENT _IOW('n', 3, struct ntsync_event_args)
|
||||
#define NTSYNC_IOC_SEM_RELEASE _IOWR('n', 4, uint32_t)
|
||||
#define NTSYNC_IOC_MUTEX_UNLOCK _IOWR('n', 5, struct ntsync_mutex_args)
|
||||
#define NTSYNC_IOC_EVENT_SET _IOR('n', 6, uint32_t)
|
||||
#define NTSYNC_IOC_EVENT_RESET _IOR('n', 7, uint32_t)
|
||||
#define NTSYNC_IOC_EVENT_PULSE _IOR('n', 8, uint32_t)
|
||||
#define NTSYNC_IOC_SEM_READ _IOR('n', 9, struct ntsync_sem_args)
|
||||
#define NTSYNC_IOC_MUTEX_READ _IO('n', 10) /* sp */
|
||||
#define NTSYNC_IOC_EVENT_READ _IOR('n', 11, struct ntsync_event_args)
|
||||
#define NTSYNC_IOC_MUTEX_KILL _IOW('n', 12, uint32_t)
|
||||
#define NTSYNC_IOC_WAIT_ANY _IOW('n', 13, struct ntsync_wait_args) /* sp */
|
||||
#define NTSYNC_IOC_WAIT_ALL _IOW('n', 14, struct ntsync_wait_args) /* sp */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright 2026 The FreeBSD Foundation
|
||||
*
|
||||
* This software was developed by Konstantin Belousov <kib@FreeBSD.org>
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __DEV_NTSYNCVAR_H__
|
||||
#define __DEV_NTSYNCVAR_H__
|
||||
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/queue.h>
|
||||
#include <dev/ntsync/ntsync.h>
|
||||
|
||||
enum ntsync_obj_type {
|
||||
NTSYNC_OBJ_SEM,
|
||||
NTSYNC_OBJ_MUTEX,
|
||||
NTSYNC_OBJ_EVENT,
|
||||
};
|
||||
|
||||
struct ntsync_wait_state;
|
||||
|
||||
struct ntsync_obj_waiter {
|
||||
struct ntsync_wait_state *state;
|
||||
TAILQ_ENTRY(ntsync_obj_waiter) link;
|
||||
};
|
||||
|
||||
struct ntsync_obj {
|
||||
enum ntsync_obj_type type;
|
||||
struct ntsync_priv *owner;
|
||||
TAILQ_HEAD(, ntsync_obj_waiter) waiters;
|
||||
/* any */
|
||||
bool (*is_signaled)(struct ntsync_obj *,
|
||||
struct ntsync_wait_state *state, int index);
|
||||
void (*consume)(struct ntsync_obj *, struct ntsync_wait_state *,
|
||||
int index);
|
||||
/* all */
|
||||
bool (*prepare)(struct ntsync_obj *, struct ntsync_wait_state *state,
|
||||
int index, bool *stop);
|
||||
void (*commit)(struct ntsync_obj *, struct ntsync_wait_state *state,
|
||||
int index);
|
||||
void (*post_commit)(struct ntsync_obj *,
|
||||
struct ntsync_wait_state *state, int index);
|
||||
};
|
||||
|
||||
struct ntsync_obj_sem {
|
||||
struct ntsync_obj obj;
|
||||
struct ntsync_sem_args a;
|
||||
struct ntsync_sem_args a1;
|
||||
};
|
||||
#define OBJ_TO_SEM(obj) __containerof(obj, struct ntsync_obj_sem, obj)
|
||||
|
||||
struct ntsync_obj_mutex {
|
||||
struct ntsync_obj obj;
|
||||
struct ntsync_mutex_args a;
|
||||
struct ntsync_mutex_args a1;
|
||||
bool abandoned;
|
||||
};
|
||||
#define OBJ_TO_MUTEX(obj) __containerof(obj, struct ntsync_obj_mutex, obj)
|
||||
|
||||
struct ntsync_obj_event {
|
||||
struct ntsync_obj obj;
|
||||
struct ntsync_event_args a;
|
||||
struct ntsync_event_args a1;
|
||||
bool pulse;
|
||||
};
|
||||
#define OBJ_TO_EVENT(obj) __containerof(obj, struct ntsync_obj_event, obj)
|
||||
|
||||
struct ntsync_wait_state {
|
||||
struct ntsync_wait_args *nwa;
|
||||
struct ntsync_priv *owner;
|
||||
struct ntsync_obj_waiter waiters[NTSYNC_MAX_WAIT_COUNT + 1];
|
||||
int fds[NTSYNC_MAX_WAIT_COUNT];
|
||||
struct file *fps[NTSYNC_MAX_WAIT_COUNT];
|
||||
struct file *fp_alert;
|
||||
int obj_count;
|
||||
struct ntsync_obj *objs[NTSYNC_MAX_WAIT_COUNT + 1];
|
||||
struct ntsync_obj_event *alert_event;
|
||||
sbintime_t sb;
|
||||
int error;
|
||||
int index;
|
||||
bool any;
|
||||
bool all;
|
||||
bool ready;
|
||||
};
|
||||
|
||||
struct ntsync_priv {
|
||||
struct mtx lock;
|
||||
unsigned objs_cnt;
|
||||
bool closed;
|
||||
};
|
||||
|
||||
#define NTSYNC_PRIV_LOCK(priv) mtx_lock(&priv->lock)
|
||||
#define NTSYNC_PRIV_UNLOCK(priv) mtx_unlock(&priv->lock)
|
||||
#define NTSYNC_PRIV_ASSERT(priv) mtx_assert(&priv->lock, MA_OWNED)
|
||||
|
||||
extern struct cdevsw ntsync_cdevsw;
|
||||
|
||||
struct file;
|
||||
struct thread;
|
||||
int ntsync_sem_release(struct thread *td, struct file *fp, uint32_t *val);
|
||||
int ntsync_sem_read(struct thread *td, struct file *fp,
|
||||
struct ntsync_sem_args *a);
|
||||
int ntsync_mutex_unlock(struct thread *td, struct file *fp,
|
||||
struct ntsync_mutex_args *a);
|
||||
int ntsync_mutex_kill(struct thread *td, struct file *fp, uint32_t val);
|
||||
int ntsync_mutex_read(struct thread *td, struct file *fp,
|
||||
struct ntsync_mutex_args *a, bool *doco);
|
||||
int ntsync_event_set(struct thread *td, struct file *fp, uint32_t *val);
|
||||
int ntsync_event_reset(struct thread *td, struct file *fp, uint32_t *val);
|
||||
int ntsync_event_pulse(struct thread *td, struct file *fp, uint32_t *val);
|
||||
int ntsync_event_read(struct thread *td, struct file *fp,
|
||||
struct ntsync_event_args *a);
|
||||
|
||||
#endif
|
||||
@@ -296,6 +296,7 @@ SUBDIR= \
|
||||
nlsysevent \
|
||||
nge \
|
||||
nmdm \
|
||||
ntsync \
|
||||
nullfs \
|
||||
${_ntb} \
|
||||
nvd \
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
.PATH: ${SRCTOP}/sys/dev/ntsync
|
||||
|
||||
KMOD= ntsync
|
||||
SRCS= ntsync.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
@@ -73,6 +73,7 @@ struct nameidata;
|
||||
#define DTYPE_TIMERFD 14 /* timerfd */
|
||||
#define DTYPE_INOTIFY 15 /* inotify descriptor */
|
||||
#define DTYPE_JAILDESC 16 /* jail descriptor */
|
||||
#define DTYPE_NTSYNC 17 /* /dev/ntsync */
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
|
||||
Reference in New Issue
Block a user