Date: Sun, 31 May 2026 17:19:57 +0000 From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 510ee6698d37 - main - linux_ntsync: linux compat shim for ntsync(9) Message-ID: <6a1c6dbd.3efb2.7c6d34dd@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=510ee6698d377f4a9a4eeb08d9dc17bdc72ad5ab commit 510ee6698d377f4a9a4eeb08d9dc17bdc72ad5ab Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2026-05-19 02:23:33 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2026-05-31 17:17:07 +0000 linux_ntsync: linux compat shim for ntsync(9) Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D57038 --- sys/dev/ntsync/linux_ntsync.c | 302 ++++++++++++++++++++++++++++++++++++++ sys/dev/ntsync/linux_ntsync.h | 62 ++++++++ sys/modules/Makefile | 1 + sys/modules/linux_ntsync/Makefile | 6 + 4 files changed, 371 insertions(+) diff --git a/sys/dev/ntsync/linux_ntsync.c b/sys/dev/ntsync/linux_ntsync.c new file mode 100644 index 000000000000..064e8c6aede9 --- /dev/null +++ b/sys/dev/ntsync/linux_ntsync.c @@ -0,0 +1,302 @@ +/* + * 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. + */ + +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/file.h> +#include <sys/filedesc.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/proc.h> +#include <sys/vnode.h> +#include <dev/ntsync/ntsyncvar.h> + +#include <machine/../linux/linux.h> +#include <machine/../linux/linux_proto.h> +#include <compat/linux/linux_common.h> +#include <compat/linux/linux_ioctl.h> +#include <dev/ntsync/linux_ntsync.h> + +MODULE_DEPEND(linux_ntsync, linux, 1, 1, 1); +MODULE_DEPEND(linux_ntsync, ntsync, 1, 1, 1); + +static linux_ioctl_function_t linux_ntsync_ioctl; +static struct linux_ioctl_handler linux_ntsync_handler = {linux_ntsync_ioctl, + LNTSYNC_IOCTL_MIN, LNTSYNC_IOCTL_MAX}; + +static int +linux_ntsync_modevent(module_t mod __unused, int type, void *data __unused) +{ + int error; + + error = 0; + switch (type) { + case MOD_LOAD: + error = linux_ioctl_register_handler(&linux_ntsync_handler); + if (error != 0) { + printf("linux_ntsync: cannot register ioctl handler, " + "error %d\n", error); + } else if (bootverbose) + printf("linux_ntsync\n"); + break; + + case MOD_UNLOAD: + linux_ioctl_unregister_handler(&linux_ntsync_handler); + break; + + case MOD_SHUTDOWN: + break; + + default: + error = EOPNOTSUPP; + } + + return (error); +} + +DEV_MODULE(linux_ntsync, linux_ntsync_modevent, NULL); +MODULE_VERSION(linux_ntsync, 1); + +/* XXXKIB no translation of structs */ +static void +ntsync_lsa_to_sa(struct ntsync_sem_args *sa, + const struct linux_ntsync_sem_args *lsa) +{ + memcpy(sa, lsa, sizeof(*sa)); +} + +static void +ntsync_sa_to_lsa(struct linux_ntsync_sem_args *lsa, + const struct ntsync_sem_args *sa) +{ + memcpy(lsa, sa, sizeof(*lsa)); +} + +static void +ntsync_lma_to_ma(struct ntsync_mutex_args *ma, + const struct linux_ntsync_mutex_args *lma) +{ + memcpy(ma, lma, sizeof(*ma)); +} + +static void +ntsync_ma_to_lma(struct linux_ntsync_mutex_args *ma, + const struct ntsync_mutex_args *lma) +{ + memcpy(ma, lma, sizeof(*ma)); +} + +static void +ntsync_lea_to_ea(struct ntsync_event_args *ea, + const struct linux_ntsync_event_args *lea) +{ + memcpy(ea, lea, sizeof(*ea)); +} + +static void +ntsync_ea_to_lea(struct linux_ntsync_event_args *lea, + const struct ntsync_event_args *ea) +{ + memcpy(lea, ea, sizeof(*lea)); +} + +static void +ntsync_lwa_to_wa(struct ntsync_wait_args *wa, + const struct linux_ntsync_wait_args *lwa) +{ + memcpy(wa, lwa, sizeof(*wa)); +} + +static void +ntsync_wa_to_lwa(struct linux_ntsync_wait_args *lwa, + const struct ntsync_wait_args *wa) +{ + memcpy(lwa, wa, sizeof(*lwa)); +} + +static int +linux_ntsync_cdev_ioctl(struct thread *td, u_long cmd, void *data, + struct file *fp) +{ + struct cdev *dev; + struct cdevsw *dsw; + struct vnode *vp; + struct file *fpop; + int error, ref; + + if (fp->f_type != DTYPE_VNODE) + return (error = ENOIOCTL); + + vp = fp->f_vnode; + if (vp->v_type != VCHR) + return (ENOIOCTL); + dev = vp->v_rdev; + dsw = dev_refthread(dev, &ref); + if (dsw == NULL) + return (ENXIO); + if (dsw != &ntsync_cdevsw) { + error = ENOIOCTL; + } else { + fpop = td->td_fpop; + td->td_fpop = fp; + error = dsw->d_ioctl(dev, cmd, data, 0, td); + td->td_fpop = fpop; + } + dev_relthread(dev, ref); + return (error); +} + +static int +linux_ntsync_ioctl(struct thread *td, struct linux_ioctl_args *args) +{ + struct file *fp; + void *data; + struct linux_ntsync_sem_args lsa; + struct linux_ntsync_mutex_args lma; + struct linux_ntsync_event_args lea; + struct linux_ntsync_wait_args lwa; + struct ntsync_sem_args sa; + struct ntsync_mutex_args ma; + struct ntsync_event_args ea; + struct ntsync_wait_args wa; + uint32_t val; + int error, error1, lcmd; + bool doco; + + lcmd = args->cmd; + data = (void *)args->arg; + + error = fget_cap(td, args->fd, &cap_no_rights, NULL, &fp, NULL); + if (error != 0) + goto out; + + doco = false; + switch (lcmd) { + case LNTSYNC_IOC_CREATE_SEM: + error = copyin(data, &lsa, sizeof(lsa)); + ntsync_lsa_to_sa(&sa, &lsa); + if (error == 0) { + error = linux_ntsync_cdev_ioctl(td, + NTSYNC_IOC_CREATE_SEM, &sa, fp); + } + break; + case LNTSYNC_IOC_CREATE_MUTEX: + error = copyin(data, &lma, sizeof(lma)); + ntsync_lma_to_ma(&ma, &lma); + if (error == 0) { + error = linux_ntsync_cdev_ioctl(td, + NTSYNC_IOC_CREATE_MUTEX, &ma, fp); + } + break; + case LNTSYNC_IOC_CREATE_EVENT: + error = copyin(data, &lea, sizeof(lea)); + ntsync_lea_to_ea(&ea, &lea); + if (error == 0) { + error = linux_ntsync_cdev_ioctl(td, + NTSYNC_IOC_CREATE_EVENT, &ea, fp); + } + break; + case LNTSYNC_IOC_WAIT_ANY: + error = copyin(data, &lwa, sizeof(lwa)); + ntsync_lwa_to_wa(&wa, &lwa); + if (error == 0) { + error = linux_ntsync_cdev_ioctl(td, + NTSYNC_IOC_WAIT_ANY, &wa, fp); + if (error == 0 || error == EOWNERDEAD) { + ntsync_wa_to_lwa(&lwa, &wa); + error1 = copyout(&lwa, data, sizeof(lwa)); + if (error == 0) + error = error1; + } + } + break; + case LNTSYNC_IOC_WAIT_ALL: + error = copyin(data, &lwa, sizeof(lwa)); + ntsync_lwa_to_wa(&wa, &lwa); + if (error == 0) { + error = linux_ntsync_cdev_ioctl(td, + NTSYNC_IOC_WAIT_ALL, &wa, fp); + if (error == 0 || error == EOWNERDEAD) { + ntsync_wa_to_lwa(&lwa, &wa); + error1 = copyout(&lwa, data, sizeof(lwa)); + if (error == 0) + error = error1; + } + } + break; + case LNTSYNC_IOC_SEM_RELEASE: + error = copyin(data, &val, sizeof(val)); + if (error == 0) { + error = ntsync_sem_release(td, fp, &val); + if (error == 0) + error = copyout(&val, data, sizeof(val)); + } + break; + case LNTSYNC_IOC_SEM_READ: + error = ntsync_sem_read(td, fp, &sa); + if (error == 0) { + ntsync_sa_to_lsa(&lsa, &sa); + error = copyout(&lsa, data, sizeof(lsa)); + } + break; + case LNTSYNC_IOC_MUTEX_UNLOCK: + error = copyin(data, &lma, sizeof(lma)); + ntsync_lma_to_ma(&ma, &lma); + if (error == 0) { + error = ntsync_mutex_unlock(td, fp, &ma); + if (error == 0) { + ntsync_ma_to_lma(&lma, &ma); + error = copyout(&lma, data, sizeof(lma)); + } + } + break; + case LNTSYNC_IOC_MUTEX_KILL: + error = copyin(data, &val, sizeof(val)); + if (error == 0) + error = ntsync_mutex_kill(td, fp, val); + break; + case LNTSYNC_IOC_MUTEX_READ: + error = ntsync_mutex_read(td, fp, &ma, &doco); + if (doco) { + ntsync_ma_to_lma(&lma, &ma); + error1 = copyout(&lma, data, sizeof(lma)); + if (error == 0) + error = error1; + } + break; + case LNTSYNC_IOC_EVENT_SET: + error = ntsync_event_set(td, fp, &val); + if (error == 0) + error = copyout(&val, data, sizeof(val)); + break; + case LNTSYNC_IOC_EVENT_RESET: + error = ntsync_event_reset(td, fp, &val); + if (error == 0) + error = copyout(&val, data, sizeof(val)); + break; + case LNTSYNC_IOC_EVENT_PULSE: + error = ntsync_event_pulse(td, fp, &val); + if (error == 0) + error = copyout(&val, data, sizeof(val)); + break; + case LNTSYNC_IOC_EVENT_READ: + error = ntsync_event_read(td, fp, &ea); + if (error == 0) { + ntsync_ea_to_lea(&lea, &ea); + error = copyout(&lea, data, sizeof(lea)); + } + break; + default: + error = ENOTTY; + break; + } + fdrop(fp, td); +out: + return (error); +} diff --git a/sys/dev/ntsync/linux_ntsync.h b/sys/dev/ntsync/linux_ntsync.h new file mode 100644 index 000000000000..412eca00bb1e --- /dev/null +++ b/sys/dev/ntsync/linux_ntsync.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Kernel support for NT synchronization primitive emulation + * + * Copyright (C) 2021-2022 Elizabeth Figura <zfigura@codeweavers.com> + */ + +#ifndef __LINUX_NTSYNC_H +#define __LINUX_NTSYNC_H + +#include <sys/types.h> + +typedef uint32_t __u32; +typedef uint64_t __u64; + +struct linux_ntsync_sem_args { + __u32 count; + __u32 max; +}; + +struct linux_ntsync_mutex_args { + __u32 owner; + __u32 count; +}; + +struct linux_ntsync_event_args { + __u32 manual; + __u32 signaled; +}; + +#define LINUX_NTSYNC_WAIT_REALTIME 0x1 + +struct linux_ntsync_wait_args { + __u64 timeout; + __u64 objs; + __u32 count; + __u32 index; + __u32 flags; + __u32 owner; + __u32 alert; + __u32 pad; +}; + +#define LNTSYNC_IOC_CREATE_SEM 0x40084e80 +#define LNTSYNC_IOC_WAIT_ANY 0xc0284e82 +#define LNTSYNC_IOC_WAIT_ALL 0xc0284e83 +#define LNTSYNC_IOC_CREATE_MUTEX 0x40084e84 +#define LNTSYNC_IOC_CREATE_EVENT 0x40084e87 +#define LNTSYNC_IOC_SEM_RELEASE 0xc0044e81 +#define LNTSYNC_IOC_MUTEX_UNLOCK 0xc0084e85 +#define LNTSYNC_IOC_MUTEX_KILL 0x40044e86 +#define LNTSYNC_IOC_EVENT_SET 0x80044e88 +#define LNTSYNC_IOC_EVENT_RESET 0x80044e89 +#define LNTSYNC_IOC_EVENT_PULSE 0x80044e8a +#define LNTSYNC_IOC_SEM_READ 0x80084e8b +#define LNTSYNC_IOC_MUTEX_READ 0x80084e8c +#define LNTSYNC_IOC_EVENT_READ 0x80084e8d + +#define LNTSYNC_IOCTL_MIN 0x4e80 +#define LNTSYNC_IOCTL_MAX 0x4eff + +#endif diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 9b31035aa89d..13100cd3fe54 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -543,6 +543,7 @@ SUBDIR+= fdt ${MACHINE_CPUARCH} == "i386" SUBDIR+= linprocfs SUBDIR+= linsysfs +SUBDIR+= linux_ntsync .endif .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" SUBDIR+= linux diff --git a/sys/modules/linux_ntsync/Makefile b/sys/modules/linux_ntsync/Makefile new file mode 100644 index 000000000000..4e186c5cdf4f --- /dev/null +++ b/sys/modules/linux_ntsync/Makefile @@ -0,0 +1,6 @@ +.PATH: ${SRCTOP}/sys/dev/ntsync + +KMOD= linux_ntsync +SRCS= linux_ntsync.c + +.include <bsd.kmod.mk>home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a1c6dbd.3efb2.7c6d34dd>
