diff options
Diffstat (limited to 'util')
-rw-r--r-- | util/Makefile.objs | 1 | ||||
-rw-r--r-- | util/sys_membarrier.c | 50 |
2 files changed, 51 insertions, 0 deletions
diff --git a/util/Makefile.objs b/util/Makefile.objs index ae90b9963d..728c3541db 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -33,6 +33,7 @@ util-obj-y += throttle.o util-obj-y += getauxval.o util-obj-y += readline.o util-obj-y += rcu.o +util-obj-$(CONFIG_MEMBARRIER) += sys_membarrier.o util-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o util-obj-y += qemu-coroutine-sleep.o util-obj-y += coroutine-$(CONFIG_COROUTINE_BACKEND).o diff --git a/util/sys_membarrier.c b/util/sys_membarrier.c new file mode 100644 index 0000000000..8dcb53e63e --- /dev/null +++ b/util/sys_membarrier.c @@ -0,0 +1,50 @@ +/* + * Process-global memory barriers + * + * Copyright (c) 2018 Red Hat, Inc. + * + * Author: Paolo Bonzini <pbonzini@redhat.com> + */ + +#include <qemu/osdep.h> +#include <qemu/sys_membarrier.h> +#include <qemu/error-report.h> + +#ifdef CONFIG_LINUX +#include <linux/membarrier.h> +#include <sys/syscall.h> + +static int +membarrier(int cmd, int flags) +{ + return syscall(__NR_membarrier, cmd, flags); +} +#endif + +void smp_mb_global(void) +{ +#if defined CONFIG_WIN32 + FlushProcessWriteBuffers(); +#elif defined CONFIG_LINUX + membarrier(MEMBARRIER_CMD_SHARED, 0); +#else +#error --enable-membarrier is not supported on this operating system. +#endif +} + +void smp_mb_global_init(void) +{ +#ifdef CONFIG_LINUX + int ret = membarrier(MEMBARRIER_CMD_QUERY, 0); + if (ret < 0) { + error_report("This QEMU binary requires the membarrier system call."); + error_report("Please upgrade your system to a newer version of Linux"); + exit(1); + } + if (!(ret & MEMBARRIER_CMD_SHARED)) { + error_report("This QEMU binary requires MEMBARRIER_CMD_SHARED support."); + error_report("Please upgrade your system to a newer version of Linux"); + exit(1); + } +#endif +} |