Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Apr 2026 19:21:26 +0000
From:      Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Cc:        Ricardo Branco <rbranco@suse.de>
Subject:   git: 1594fe0b1029 - main - linux: Add support for membarrier(2)
Message-ID:  <69e91fb6.1c2a7.69fa18e8@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by pouria:

URL: https://cgit.FreeBSD.org/src/commit/?id=1594fe0b1029f246b3a14c8b21637091968362aa

commit 1594fe0b1029f246b3a14c8b21637091968362aa
Author:     Ricardo Branco <rbranco@suse.de>
AuthorDate: 2026-04-18 10:11:44 +0000
Commit:     Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
CommitDate: 2026-04-22 19:15:30 +0000

    linux: Add support for membarrier(2)
    
    FreeBSD has a native membarrier(2) syscall which is mostly compatible
    with Linux. This is a thin wrapper around kern_membarrier() that
    translates all available commands and flags.
    
    Also update the syscalls.master prototypes to match the Linux 5.10+
    three-argument form.  Pre-5.10 binaries using the two-argument form
    continue to work: cpu_id is only consulted for RSEQ commands, which
    FreeBSD does not support and which kern_membarrier() rejects with
    EINVAL, matching Linux semantics.
    
    Signed-off-by:  Ricardo Branco <rbranco@suse.de>
    PR:             281691
    Reviewed by:    kib, pouria
    Pull-Request:   https://github.com/freebsd/freebsd-src/pull/2147
---
 sys/amd64/linux/syscalls.master   |  3 +-
 sys/amd64/linux32/syscalls.master |  3 +-
 sys/arm64/linux/syscalls.master   |  3 +-
 sys/compat/linux/linux_dummy.c    |  2 --
 sys/compat/linux/linux_misc.c     | 64 +++++++++++++++++++++++++++++++++++++++
 sys/compat/linux/linux_misc.h     | 16 ++++++++++
 sys/i386/linux/syscalls.master    |  3 +-
 7 files changed, 88 insertions(+), 6 deletions(-)

diff --git a/sys/amd64/linux/syscalls.master b/sys/amd64/linux/syscalls.master
index 5e1394751ef6..b3bbd917c013 100644
--- a/sys/amd64/linux/syscalls.master
+++ b/sys/amd64/linux/syscalls.master
@@ -1976,7 +1976,8 @@
 324	AUE_NULL	STD {
 		int linux_membarrier(
 		    l_int cmd,
-		    l_int flags
+		    l_uint flags,
+		    l_int cpu_id
 		);
 	}
 ; Linux 4.4:
diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master
index 7bd522a598e8..fab68854af03 100644
--- a/sys/amd64/linux32/syscalls.master
+++ b/sys/amd64/linux32/syscalls.master
@@ -2194,7 +2194,8 @@
 375	AUE_NULL	STD {
 		int linux_membarrier(
 		    l_int cmd,
-		    l_int flags
+		    l_uint flags,
+		    l_int cpu_id
 		);
 	}
 ; Linux 4.4:
diff --git a/sys/arm64/linux/syscalls.master b/sys/arm64/linux/syscalls.master
index 2babdcaf03bf..f4ab6f49c363 100644
--- a/sys/arm64/linux/syscalls.master
+++ b/sys/arm64/linux/syscalls.master
@@ -1655,7 +1655,8 @@
 283	AUE_NULL	STD	{
 		int linux_membarrier(
 		    l_int cmd,
-		    l_int flags
+		    l_uint flags,
+		    l_int cpu_id
 		);
 	}
 284	AUE_NULL	STD	{
diff --git a/sys/compat/linux/linux_dummy.c b/sys/compat/linux/linux_dummy.c
index 46f98f4da1eb..dfabf33eb8a6 100644
--- a/sys/compat/linux/linux_dummy.c
+++ b/sys/compat/linux/linux_dummy.c
@@ -106,8 +106,6 @@ DUMMY(bpf);
 DUMMY(execveat);
 /* Linux 4.2: */
 DUMMY(userfaultfd);
-/* Linux 4.3: */
-DUMMY(membarrier);
 /* Linux 4.4: */
 DUMMY(mlock2);
 /* Linux 4.6: */
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 85088e8ed7ca..4c8ad669f03c 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -35,6 +35,7 @@
 #include <sys/imgact.h>
 #include <sys/limits.h>
 #include <sys/lock.h>
+#include <sys/membarrier.h>
 #include <sys/msgbuf.h>
 #include <sys/mqueue.h>
 #include <sys/mutex.h>
@@ -3115,4 +3116,67 @@ linux_kcmp(struct thread *td, struct linux_kcmp_args *args)
 	    args->idx));
 }
 
+int
+linux_membarrier(struct thread *td, struct linux_membarrier_args *args)
+{
+	static const struct {
+		int linux_cmd;
+		int freebsd_cmd;
+	} cmds[] = {
+		{ LINUX_MEMBARRIER_CMD_QUERY,
+		    MEMBARRIER_CMD_QUERY },
+		{ LINUX_MEMBARRIER_CMD_GLOBAL,
+		    MEMBARRIER_CMD_GLOBAL },
+		{ LINUX_MEMBARRIER_CMD_GLOBAL_EXPEDITED,
+		    MEMBARRIER_CMD_GLOBAL_EXPEDITED },
+		{ LINUX_MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED,
+		    MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED },
+		{ LINUX_MEMBARRIER_CMD_PRIVATE_EXPEDITED,
+		    MEMBARRIER_CMD_PRIVATE_EXPEDITED },
+		{ LINUX_MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED,
+		    MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED },
+		{ LINUX_MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE,
+		    MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE },
+		{ LINUX_MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE,
+		    MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE },
+		{ LINUX_MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ,
+		    MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ },
+		{ LINUX_MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ,
+		    MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ },
+		{ LINUX_MEMBARRIER_CMD_GET_REGISTRATIONS,
+		    MEMBARRIER_CMD_GET_REGISTRATIONS },
+	};
+	int cmd, error, flags, i, mask;
+
+	cmd = -1;
+	for (i = 0; i < nitems(cmds); i++) {
+		if (args->cmd == cmds[i].linux_cmd) {
+			cmd = cmds[i].freebsd_cmd;
+			break;
+		}
+	}
+
+	if (cmd == -1 || (args->flags & ~LINUX_MEMBARRIER_CMD_FLAG_CPU) != 0)
+		return (EINVAL);
+
+	flags = 0;
+	if ((args->flags & LINUX_MEMBARRIER_CMD_FLAG_CPU) != 0)
+		flags |= MEMBARRIER_CMD_FLAG_CPU;
+
+	error = kern_membarrier(td, cmd, flags, args->cpu_id);
+	if (error != 0)
+		return (error);
+
+	if (args->cmd == LINUX_MEMBARRIER_CMD_QUERY ||
+	    args->cmd == LINUX_MEMBARRIER_CMD_GET_REGISTRATIONS) {
+		mask = td->td_retval[0];
+		td->td_retval[0] = 0;
+		for (i = 0; i < nitems(cmds); i++)
+			if ((mask & cmds[i].freebsd_cmd) != 0)
+				td->td_retval[0] |= cmds[i].linux_cmd;
+	}
+
+	return (0);
+}
+
 MODULE_DEPEND(linux, mqueuefs, 1, 1, 1);
diff --git a/sys/compat/linux/linux_misc.h b/sys/compat/linux/linux_misc.h
index 269fb734a69a..2044f23f30ee 100644
--- a/sys/compat/linux/linux_misc.h
+++ b/sys/compat/linux/linux_misc.h
@@ -229,4 +229,20 @@ struct syscall_info {
 #define	LINUX_KCMP_EPOLL_TFD		7
 #define	LINUX_KCMP_TYPES		8
 
+/* Linux membarrier commands from <linux/membarrier.h> */
+#define	LINUX_MEMBARRIER_CMD_QUERY				0
+#define	LINUX_MEMBARRIER_CMD_GLOBAL				(1 << 0)
+#define	LINUX_MEMBARRIER_CMD_GLOBAL_EXPEDITED			(1 << 1)
+#define	LINUX_MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED		(1 << 2)
+#define	LINUX_MEMBARRIER_CMD_PRIVATE_EXPEDITED			(1 << 3)
+#define	LINUX_MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED		(1 << 4)
+#define	LINUX_MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE	(1 << 5)
+#define	LINUX_MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE (1 << 6)
+#define	LINUX_MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ		(1 << 7)
+#define	LINUX_MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ	(1 << 8)
+#define	LINUX_MEMBARRIER_CMD_GET_REGISTRATIONS			(1 << 9)
+
+/* Linux membarrier flags from <linux/membarrier.h> */
+#define	LINUX_MEMBARRIER_CMD_FLAG_CPU				(1 << 0)
+
 #endif	/* _LINUX_MISC_H_ */
diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master
index 2113ea51ac5d..b93f28acae14 100644
--- a/sys/i386/linux/syscalls.master
+++ b/sys/i386/linux/syscalls.master
@@ -2206,7 +2206,8 @@
 375	AUE_NULL	STD {
 		int linux_membarrier(
 		    l_int cmd,
-		    l_int flags
+		    l_uint flags,
+		    l_int cpu_id
 		);
 	}
 ; Linux 4.4:


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69e91fb6.1c2a7.69fa18e8>