Enable the VFIO subsystem to compile on macOS/Darwin in addition to
Linux. This is build infrastructure only — no Apple-specific device
code is added yet.
Key changes:
- Add CONFIG_DARWIN Kconfig symbol and propagate it through the build
system so that VFIO and VFIO_PCI are selectable on Darwin hosts.
- Provide minimal <linux/types.h> and <linux/ioctl.h> shim headers
under include/compat/ so the Linux UAPI VFIO headers parse on macOS.
- Widen CONFIG_LINUX guards to CONFIG_LINUX || CONFIG_DARWIN in the
VFIO device, helpers, and migration headers.
- Make container-legacy.c (the Linux /dev/vfio ioctl container) build
only on Linux, and restrict IOMMUFD to Linux in Kconfig.
- Remove the CONFIG_EVENTFD guard around event_notifier_init_fd() so
pipe-based EventNotifiers can be initialized on Darwin.
- Mark vfio-pci as not user-creatable on Darwin since the Linux VFIO
kernel driver is not available; the Apple-specific device type will
be added in a subsequent commit.
Signed-off-by: Scott J. Goldman <scottjgo@gmail.com>
---
Kconfig.host | 3 +++
backends/Kconfig | 2 +-
hw/vfio/Kconfig | 4 ++--
hw/vfio/meson.build | 4 +++-
hw/vfio/pci.c | 3 +++
hw/vfio/vfio-helpers.h | 2 +-
hw/vfio/vfio-migration-internal.h | 4 ++--
include/compat/linux/ioctl.h | 2 ++
include/compat/linux/types.h | 26 ++++++++++++++++++++++++++
include/hw/vfio/vfio-device.h | 4 ++--
meson.build | 10 +++++++++-
util/event_notifier-posix.c | 5 ++---
12 files changed, 56 insertions(+), 13 deletions(-)
create mode 100644 include/compat/linux/ioctl.h
create mode 100644 include/compat/linux/types.h
diff --git a/Kconfig.host b/Kconfig.host
index 933425c74b..bb2780293c 100644
--- a/Kconfig.host
+++ b/Kconfig.host
@@ -5,6 +5,9 @@
config LINUX
bool
+config DARWIN
+ bool
+
config LIBCBOR
bool
diff --git a/backends/Kconfig b/backends/Kconfig
index d3dbe19868..d1be4148d3 100644
--- a/backends/Kconfig
+++ b/backends/Kconfig
@@ -2,7 +2,7 @@ source tpm/Kconfig
config IOMMUFD
bool
- depends on VFIO
+ depends on VFIO && LINUX
config SPDM_SOCKET
bool
diff --git a/hw/vfio/Kconfig b/hw/vfio/Kconfig
index 27de24e4db..a409483c34 100644
--- a/hw/vfio/Kconfig
+++ b/hw/vfio/Kconfig
@@ -2,14 +2,14 @@
config VFIO
bool
- depends on LINUX
+ depends on LINUX || DARWIN
config VFIO_PCI
bool
default y
select VFIO
select EDID
- depends on LINUX && PCI
+ depends on (LINUX || DARWIN) && PCI
config VFIO_CCW
bool
diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
index 82f68698fb..1ee9c11d5b 100644
--- a/hw/vfio/meson.build
+++ b/hw/vfio/meson.build
@@ -4,9 +4,11 @@ vfio_ss = ss.source_set()
vfio_ss.add(files(
'listener.c',
'container.c',
- 'container-legacy.c',
'helpers.c',
))
+if host_os == 'linux'
+ vfio_ss.add(files('container-legacy.c'))
+endif
vfio_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr.c'))
vfio_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files(
'pci-quirks.c',
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index ee1a42e7e0..5a1c2d8c2e 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3862,6 +3862,9 @@ static void vfio_pci_class_init(ObjectClass *klass, const void *data)
#endif
dc->vmsd = &vfio_cpr_pci_vmstate;
dc->desc = "VFIO-based PCI device assignment";
+#ifdef CONFIG_DARWIN
+ dc->user_creatable = false;
+#endif
pdc->realize = vfio_pci_realize;
object_class_property_set_description(klass, /* 1.3 */
diff --git a/hw/vfio/vfio-helpers.h b/hw/vfio/vfio-helpers.h
index 54a327ffbc..2afb360797 100644
--- a/hw/vfio/vfio-helpers.h
+++ b/hw/vfio/vfio-helpers.h
@@ -9,7 +9,7 @@
#ifndef HW_VFIO_VFIO_HELPERS_H
#define HW_VFIO_VFIO_HELPERS_H
-#ifdef CONFIG_LINUX
+#if defined(CONFIG_LINUX) || defined(CONFIG_DARWIN)
#include <linux/vfio.h>
extern int vfio_kvm_device_fd;
diff --git a/hw/vfio/vfio-migration-internal.h b/hw/vfio/vfio-migration-internal.h
index 814fbd9eba..566cd6a871 100644
--- a/hw/vfio/vfio-migration-internal.h
+++ b/hw/vfio/vfio-migration-internal.h
@@ -9,7 +9,7 @@
#ifndef HW_VFIO_VFIO_MIGRATION_INTERNAL_H
#define HW_VFIO_VFIO_MIGRATION_INTERNAL_H
-#ifdef CONFIG_LINUX
+#if defined(CONFIG_LINUX) || defined(CONFIG_DARWIN)
#include <linux/vfio.h>
#endif
@@ -62,7 +62,7 @@ bool vfio_device_state_is_precopy(VFIODevice *vbasedev);
int vfio_save_device_config_state(QEMUFile *f, void *opaque, Error **errp);
int vfio_load_device_config_state(QEMUFile *f, void *opaque);
-#ifdef CONFIG_LINUX
+#if defined(CONFIG_LINUX) || defined(CONFIG_DARWIN)
int vfio_migration_set_state(VFIODevice *vbasedev,
enum vfio_device_mig_state new_state,
enum vfio_device_mig_state recover_state,
diff --git a/include/compat/linux/ioctl.h b/include/compat/linux/ioctl.h
new file mode 100644
index 0000000000..2c789fefc6
--- /dev/null
+++ b/include/compat/linux/ioctl.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* empty Darwin shim - ioctl macros not needed */
diff --git a/include/compat/linux/types.h b/include/compat/linux/types.h
new file mode 100644
index 0000000000..d6620aaf7f
--- /dev/null
+++ b/include/compat/linux/types.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Darwin shim for <linux/types.h>
+ *
+ * The Linux UAPI headers that QEMU copies into linux-headers/ expect
+ * these typedefs from <linux/types.h>. Provide the small subset we
+ * need so those headers parse on macOS.
+ */
+#ifndef COMPAT_LINUX_TYPES_H
+#define COMPAT_LINUX_TYPES_H
+
+#include <stdint.h>
+
+typedef uint8_t __u8;
+typedef uint16_t __u16;
+typedef uint32_t __u32;
+typedef uint64_t __u64;
+typedef int8_t __s8;
+typedef int16_t __s16;
+typedef int32_t __s32;
+typedef int64_t __s64;
+typedef int64_t loff_t;
+
+typedef __u64 __aligned_u64 __attribute__((aligned(8)));
+
+#endif /* COMPAT_LINUX_TYPES_H */
diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
index 828a31c006..17c5db369c 100644
--- a/include/hw/vfio/vfio-device.h
+++ b/include/hw/vfio/vfio-device.h
@@ -23,7 +23,7 @@
#include "system/memory.h"
#include "qemu/queue.h"
-#ifdef CONFIG_LINUX
+#if defined(CONFIG_LINUX) || defined(CONFIG_DARWIN)
#include <linux/vfio.h>
#endif
#include "system/system.h"
@@ -171,7 +171,7 @@ VFIODevice *vfio_get_vfio_device(Object *obj);
typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList;
extern VFIODeviceList vfio_device_list;
-#ifdef CONFIG_LINUX
+#if defined(CONFIG_LINUX) || defined(CONFIG_DARWIN)
/*
* How devices communicate with the server. The default option is through
* ioctl() to the kernel VFIO driver, but vfio-user can use a socket to a remote
diff --git a/meson.build b/meson.build
index daa58e46a3..b12466b730 100644
--- a/meson.build
+++ b/meson.build
@@ -764,7 +764,14 @@ if 'objc' in all_languages
add_project_arguments(objc.get_supported_arguments(qemu_common_flags + warn_flags),
native: false, language: 'objc')
endif
-if host_os == 'linux'
+if host_os == 'darwin'
+ # linux-headers/linux/vfio.h includes <linux/types.h> and <linux/ioctl.h>
+ # which are system headers on Linux but absent on macOS. Point at the
+ # static shims in include/compat/
+ add_project_arguments('-isystem', meson.current_source_dir() / 'include/compat',
+ language: all_languages)
+endif
+if host_os in ['linux', 'darwin']
add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
'-isystem', 'linux-headers',
language: all_languages)
@@ -3282,6 +3289,7 @@ host_kconfig = \
(have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
(have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
(host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \
+ (host_os == 'darwin' ? ['CONFIG_DARWIN=y'] : []) + \
(multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
(vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \
(hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : []) + \
diff --git a/util/event_notifier-posix.c b/util/event_notifier-posix.c
index 83fdbb96bb..0e05e81aca 100644
--- a/util/event_notifier-posix.c
+++ b/util/event_notifier-posix.c
@@ -20,10 +20,10 @@
#include <sys/eventfd.h>
#endif
-#ifdef CONFIG_EVENTFD
/*
* Initialize @e with existing file descriptor @fd.
- * @fd must be a genuine eventfd object, emulation with pipe won't do.
+ * On hosts without eventfd(), callers can still restore a single descriptor
+ * for cases that only need eventfd-like semantics.
*/
void event_notifier_init_fd(EventNotifier *e, int fd)
{
@@ -31,7 +31,6 @@ void event_notifier_init_fd(EventNotifier *e, int fd)
e->wfd = fd;
e->initialized = true;
}
-#endif
int event_notifier_init(EventNotifier *e, int active)
{
--
2.50.1 (Apple Git-155)