aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/linux
diff options
context:
space:
mode:
authorRicardo Branco <rbranco@suse.de>2026-04-18 10:11:44 +0000
committerPouria Mousavizadeh Tehrani <pouria@FreeBSD.org>2026-04-22 19:15:30 +0000
commit1594fe0b1029f246b3a14c8b21637091968362aa (patch)
treebb42b4388400c3e70b04086e123cfa529211a97a /sys/compat/linux
parentcff716c2854c167ef7ff3a4785f5faed9b0a4f98 (diff)
Diffstat (limited to 'sys/compat/linux')
-rw-r--r--sys/compat/linux/linux_dummy.c2
-rw-r--r--sys/compat/linux/linux_misc.c64
-rw-r--r--sys/compat/linux/linux_misc.h16
3 files changed, 80 insertions, 2 deletions
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_ */