Because those functions use kvm specific types, they need to be isolated
in another source file.
This allows us to link kvm-helpers only in configurations with
CONFIG_KVM.
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
---
hw/vfio/helpers.c | 172 -------------------------------------
hw/vfio/kvm-helpers.c | 192 ++++++++++++++++++++++++++++++++++++++++++
hw/vfio/kvm-stubs.c | 27 ++++++
hw/vfio/meson.build | 2 +
4 files changed, 221 insertions(+), 172 deletions(-)
create mode 100644 hw/vfio/kvm-helpers.c
create mode 100644 hw/vfio/kvm-stubs.c
diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 00d42d3b98e..65c6dba0428 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -22,7 +22,6 @@
#include "qemu/osdep.h"
#include <sys/ioctl.h>
-#include "system/kvm.h"
#include "exec/cpu-common.h"
#include "hw/vfio/vfio-device.h"
#include "hw/core/hw-error.h"
@@ -107,177 +106,6 @@ bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info,
return true;
}
-#ifdef CONFIG_KVM
-/*
- * We have a single VFIO pseudo device per KVM VM. Once created it lives
- * for the life of the VM. Closing the file descriptor only drops our
- * reference to it and the device's reference to kvm. Therefore once
- * initialized, this file descriptor is only released on QEMU exit and
- * we'll re-use it should another vfio device be attached before then.
- */
-int vfio_kvm_device_fd = -1;
-
-/*
- * Confidential virtual machines:
- * During reset of confidential vms, the kvm vm file descriptor changes.
- * In this case, the old vfio kvm file descriptor is
- * closed and a new descriptor is created against the new kvm vm file
- * descriptor.
- */
-
-typedef struct VFIODeviceFd {
- int fd;
- QLIST_ENTRY(VFIODeviceFd) node;
-} VFIODeviceFd;
-
-static QLIST_HEAD(, VFIODeviceFd) vfio_device_fds =
- QLIST_HEAD_INITIALIZER(vfio_device_fds);
-
-static void vfio_device_fd_list_add(int fd)
-{
- VFIODeviceFd *file_fd;
- file_fd = g_malloc0(sizeof(*file_fd));
- file_fd->fd = fd;
- QLIST_INSERT_HEAD(&vfio_device_fds, file_fd, node);
-}
-
-static void vfio_device_fd_list_remove(int fd)
-{
- VFIODeviceFd *file_fd, *next;
-
- QLIST_FOREACH_SAFE(file_fd, &vfio_device_fds, node, next) {
- if (file_fd->fd == fd) {
- QLIST_REMOVE(file_fd, node);
- g_free(file_fd);
- break;
- }
- }
-}
-
-static int vfio_device_fd_rebind(NotifierWithReturn *notifier, void *data,
- Error **errp)
-{
- VFIODeviceFd *file_fd;
- struct kvm_device_attr attr = {
- .group = KVM_DEV_VFIO_FILE,
- .attr = KVM_DEV_VFIO_FILE_ADD,
- };
- struct kvm_create_device cd = {
- .type = KVM_DEV_TYPE_VFIO,
- };
-
- /* we are not interested in pre vmfd change notification */
- if (((VmfdChangeNotifier *)data)->pre) {
- return 0;
- }
-
- if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) {
- error_setg_errno(errp, errno, "Failed to create KVM VFIO device");
- return -errno;
- }
-
- if (vfio_kvm_device_fd != -1) {
- close(vfio_kvm_device_fd);
- }
-
- vfio_kvm_device_fd = cd.fd;
-
- QLIST_FOREACH(file_fd, &vfio_device_fds, node) {
- attr.addr = (uint64_t)(unsigned long)&file_fd->fd;
- if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
- error_setg_errno(errp, errno,
- "Failed to add fd %d to KVM VFIO device",
- file_fd->fd);
- return -errno;
- }
- }
- return 0;
-}
-
-static struct NotifierWithReturn vfio_vmfd_change_notifier = {
- .notify = vfio_device_fd_rebind,
-};
-
-#endif
-
-void vfio_kvm_device_close(void)
-{
-#ifdef CONFIG_KVM
- kvm_close();
- if (vfio_kvm_device_fd != -1) {
- close(vfio_kvm_device_fd);
- vfio_kvm_device_fd = -1;
- }
-#endif
-}
-
-int vfio_kvm_device_add_fd(int fd, Error **errp)
-{
-#ifdef CONFIG_KVM
- struct kvm_device_attr attr = {
- .group = KVM_DEV_VFIO_FILE,
- .attr = KVM_DEV_VFIO_FILE_ADD,
- .addr = (uint64_t)(unsigned long)&fd,
- };
-
- if (!kvm_enabled()) {
- return 0;
- }
-
- if (vfio_kvm_device_fd < 0) {
- struct kvm_create_device cd = {
- .type = KVM_DEV_TYPE_VFIO,
- };
-
- if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) {
- error_setg_errno(errp, errno, "Failed to create KVM VFIO device");
- return -errno;
- }
-
- vfio_kvm_device_fd = cd.fd;
- /*
- * If the vm file descriptor changes, add a notifier so that we can
- * re-create the vfio_kvm_device_fd.
- */
- kvm_vmfd_add_change_notifier(&vfio_vmfd_change_notifier);
- }
-
- if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
- error_setg_errno(errp, errno, "Failed to add fd %d to KVM VFIO device",
- fd);
- return -errno;
- }
-
- vfio_device_fd_list_add(fd);
-#endif
- return 0;
-}
-
-int vfio_kvm_device_del_fd(int fd, Error **errp)
-{
-#ifdef CONFIG_KVM
- struct kvm_device_attr attr = {
- .group = KVM_DEV_VFIO_FILE,
- .attr = KVM_DEV_VFIO_FILE_DEL,
- .addr = (uint64_t)(unsigned long)&fd,
- };
-
- if (vfio_kvm_device_fd < 0) {
- error_setg(errp, "KVM VFIO device isn't created yet");
- return -EINVAL;
- }
-
- if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
- error_setg_errno(errp, errno,
- "Failed to remove fd %d from KVM VFIO device", fd);
- return -errno;
- }
-
- vfio_device_fd_list_remove(fd);
-#endif
- return 0;
-}
-
struct vfio_device_info *vfio_get_device_info(int fd)
{
struct vfio_device_info *info;
diff --git a/hw/vfio/kvm-helpers.c b/hw/vfio/kvm-helpers.c
new file mode 100644
index 00000000000..d71c9590aaa
--- /dev/null
+++ b/hw/vfio/kvm-helpers.c
@@ -0,0 +1,192 @@
+/*
+ * low level and IOMMU backend agnostic helpers used by VFIO devices,
+ * related to regions, interrupts, capabilities
+ *
+ * Copyright Red Hat, Inc. 2012
+ *
+ * Authors:
+ * Alex Williamson <alex.williamson@redhat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Based on qemu-kvm device-assignment:
+ * Adapted for KVM by Qumranet.
+ * Copyright (c) 2007, Neocleus, Alex Novik (alex@neocleus.com)
+ * Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com)
+ * Copyright (C) 2008, Qumranet, Amit Shah (amit.shah@qumranet.com)
+ * Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com)
+ * Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com)
+ */
+
+#include "qemu/osdep.h"
+#include <sys/ioctl.h>
+
+#include <linux/kvm.h>
+#include "system/kvm.h"
+#include "exec/cpu-common.h"
+#include "hw/vfio/vfio-device.h"
+#include "hw/core/hw-error.h"
+#include "qapi/error.h"
+#include "vfio-helpers.h"
+
+/*
+ * We have a single VFIO pseudo device per KVM VM. Once created it lives
+ * for the life of the VM. Closing the file descriptor only drops our
+ * reference to it and the device's reference to kvm. Therefore once
+ * initialized, this file descriptor is only released on QEMU exit and
+ * we'll re-use it should another vfio device be attached before then.
+ */
+int vfio_kvm_device_fd = -1;
+
+/*
+ * Confidential virtual machines:
+ * During reset of confidential vms, the kvm vm file descriptor changes.
+ * In this case, the old vfio kvm file descriptor is
+ * closed and a new descriptor is created against the new kvm vm file
+ * descriptor.
+ */
+
+typedef struct VFIODeviceFd {
+ int fd;
+ QLIST_ENTRY(VFIODeviceFd) node;
+} VFIODeviceFd;
+
+static QLIST_HEAD(, VFIODeviceFd) vfio_device_fds =
+ QLIST_HEAD_INITIALIZER(vfio_device_fds);
+
+static void vfio_device_fd_list_add(int fd)
+{
+ VFIODeviceFd *file_fd;
+ file_fd = g_malloc0(sizeof(*file_fd));
+ file_fd->fd = fd;
+ QLIST_INSERT_HEAD(&vfio_device_fds, file_fd, node);
+}
+
+static void vfio_device_fd_list_remove(int fd)
+{
+ VFIODeviceFd *file_fd, *next;
+
+ QLIST_FOREACH_SAFE(file_fd, &vfio_device_fds, node, next) {
+ if (file_fd->fd == fd) {
+ QLIST_REMOVE(file_fd, node);
+ g_free(file_fd);
+ break;
+ }
+ }
+}
+
+static int vfio_device_fd_rebind(NotifierWithReturn *notifier, void *data,
+ Error **errp)
+{
+ VFIODeviceFd *file_fd;
+ struct kvm_device_attr attr = {
+ .group = KVM_DEV_VFIO_FILE,
+ .attr = KVM_DEV_VFIO_FILE_ADD,
+ };
+ struct kvm_create_device cd = {
+ .type = KVM_DEV_TYPE_VFIO,
+ };
+
+ /* we are not interested in pre vmfd change notification */
+ if (((VmfdChangeNotifier *)data)->pre) {
+ return 0;
+ }
+
+ if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) {
+ error_setg_errno(errp, errno, "Failed to create KVM VFIO device");
+ return -errno;
+ }
+
+ if (vfio_kvm_device_fd != -1) {
+ close(vfio_kvm_device_fd);
+ }
+
+ vfio_kvm_device_fd = cd.fd;
+
+ QLIST_FOREACH(file_fd, &vfio_device_fds, node) {
+ attr.addr = (uint64_t)(unsigned long)&file_fd->fd;
+ if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
+ error_setg_errno(errp, errno,
+ "Failed to add fd %d to KVM VFIO device",
+ file_fd->fd);
+ return -errno;
+ }
+ }
+ return 0;
+}
+
+static struct NotifierWithReturn vfio_vmfd_change_notifier = {
+ .notify = vfio_device_fd_rebind,
+};
+
+void vfio_kvm_device_close(void)
+{
+ kvm_close();
+ if (vfio_kvm_device_fd != -1) {
+ close(vfio_kvm_device_fd);
+ vfio_kvm_device_fd = -1;
+ }
+}
+
+int vfio_kvm_device_add_fd(int fd, Error **errp)
+{
+ struct kvm_device_attr attr = {
+ .group = KVM_DEV_VFIO_FILE,
+ .attr = KVM_DEV_VFIO_FILE_ADD,
+ .addr = (uint64_t)(unsigned long)&fd,
+ };
+
+ if (!kvm_enabled()) {
+ return 0;
+ }
+
+ if (vfio_kvm_device_fd < 0) {
+ struct kvm_create_device cd = {
+ .type = KVM_DEV_TYPE_VFIO,
+ };
+
+ if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) {
+ error_setg_errno(errp, errno, "Failed to create KVM VFIO device");
+ return -errno;
+ }
+
+ vfio_kvm_device_fd = cd.fd;
+ /*
+ * If the vm file descriptor changes, add a notifier so that we can
+ * re-create the vfio_kvm_device_fd.
+ */
+ kvm_vmfd_add_change_notifier(&vfio_vmfd_change_notifier);
+ }
+
+ if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
+ error_setg_errno(errp, errno, "Failed to add fd %d to KVM VFIO device",
+ fd);
+ return -errno;
+ }
+
+ vfio_device_fd_list_add(fd);
+ return 0;
+}
+
+int vfio_kvm_device_del_fd(int fd, Error **errp)
+{
+ struct kvm_device_attr attr = {
+ .group = KVM_DEV_VFIO_FILE,
+ .attr = KVM_DEV_VFIO_FILE_DEL,
+ .addr = (uint64_t)(unsigned long)&fd,
+ };
+
+ if (vfio_kvm_device_fd < 0) {
+ error_setg(errp, "KVM VFIO device isn't created yet");
+ return -EINVAL;
+ }
+
+ if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
+ error_setg_errno(errp, errno,
+ "Failed to remove fd %d from KVM VFIO device", fd);
+ return -errno;
+ }
+
+ vfio_device_fd_list_remove(fd);
+ return 0;
+}
diff --git a/hw/vfio/kvm-stubs.c b/hw/vfio/kvm-stubs.c
new file mode 100644
index 00000000000..9593287d9c2
--- /dev/null
+++ b/hw/vfio/kvm-stubs.c
@@ -0,0 +1,27 @@
+/*
+ * Stubs for kvm helpers
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include <sys/ioctl.h>
+
+#include "hw/vfio/vfio-device.h"
+#include "qapi/error.h"
+#include "vfio-helpers.h"
+
+void vfio_kvm_device_close(void)
+{
+ return;
+}
+
+int vfio_kvm_device_add_fd(int fd, Error **errp)
+{
+ return 0;
+}
+
+int vfio_kvm_device_del_fd(int fd, Error **errp)
+{
+ return 0;
+}
diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
index 82f68698fb8..f32d8573600 100644
--- a/hw/vfio/meson.build
+++ b/hw/vfio/meson.build
@@ -7,6 +7,8 @@ vfio_ss.add(files(
'container-legacy.c',
'helpers.c',
))
+vfio_ss.add(when: 'CONFIG_KVM', if_true: files('kvm-helpers.c'),
+ if_false: files('kvm-stubs.c'))
vfio_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr.c'))
vfio_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files(
'pci-quirks.c',
--
2.47.3
On 3/12/26 23:44, Pierrick Bouvier wrote: > Because those functions use kvm specific types, they need to be isolated > in another source file. > This allows us to link kvm-helpers only in configurations with > CONFIG_KVM. > > Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> > --- > hw/vfio/helpers.c | 172 ------------------------------------- > hw/vfio/kvm-helpers.c | 192 ++++++++++++++++++++++++++++++++++++++++++ > hw/vfio/kvm-stubs.c | 27 ++++++ > hw/vfio/meson.build | 2 + > 4 files changed, 221 insertions(+), 172 deletions(-) > create mode 100644 hw/vfio/kvm-helpers.c > create mode 100644 hw/vfio/kvm-stubs.c Reviewed-by: Cédric Le Goater <clg@redhat.com> Thanks, C.
On 12/3/26 23:44, Pierrick Bouvier wrote:
> Because those functions use kvm specific types, they need to be isolated
> in another source file.
> This allows us to link kvm-helpers only in configurations with
> CONFIG_KVM.
>
> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> ---
> hw/vfio/helpers.c | 172 -------------------------------------
> hw/vfio/kvm-helpers.c | 192 ++++++++++++++++++++++++++++++++++++++++++
> hw/vfio/kvm-stubs.c | 27 ++++++
> hw/vfio/meson.build | 2 +
> 4 files changed, 221 insertions(+), 172 deletions(-)
> create mode 100644 hw/vfio/kvm-helpers.c
> create mode 100644 hw/vfio/kvm-stubs.c
> diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
> index 82f68698fb8..f32d8573600 100644
> --- a/hw/vfio/meson.build
> +++ b/hw/vfio/meson.build
> @@ -7,6 +7,8 @@ vfio_ss.add(files(
> 'container-legacy.c',
> 'helpers.c',
> ))
> +vfio_ss.add(when: 'CONFIG_KVM', if_true: files('kvm-helpers.c'),
> + if_false: files('kvm-stubs.c'))
Directly add to global stubs source set:
stub_ss.addfiles('kvm-stubs.c'))
> vfio_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr.c'))
> vfio_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files(
> 'pci-quirks.c',
On 3/12/26 8:18 PM, Philippe Mathieu-Daudé wrote:
> On 12/3/26 23:44, Pierrick Bouvier wrote:
>> Because those functions use kvm specific types, they need to be isolated
>> in another source file.
>> This allows us to link kvm-helpers only in configurations with
>> CONFIG_KVM.
>>
>> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
>> ---
>> hw/vfio/helpers.c | 172 -------------------------------------
>> hw/vfio/kvm-helpers.c | 192 ++++++++++++++++++++++++++++++++++++++++++
>> hw/vfio/kvm-stubs.c | 27 ++++++
>> hw/vfio/meson.build | 2 +
>> 4 files changed, 221 insertions(+), 172 deletions(-)
>> create mode 100644 hw/vfio/kvm-helpers.c
>> create mode 100644 hw/vfio/kvm-stubs.c
>
>
>> diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
>> index 82f68698fb8..f32d8573600 100644
>> --- a/hw/vfio/meson.build
>> +++ b/hw/vfio/meson.build
>> @@ -7,6 +7,8 @@ vfio_ss.add(files(
>> 'container-legacy.c',
>> 'helpers.c',
>> ))
>> +vfio_ss.add(when: 'CONFIG_KVM', if_true: files('kvm-helpers.c'),
>> + if_false: files('kvm-stubs.c'))
>
> Directly add to global stubs source set:
>
> stub_ss.addfiles('kvm-stubs.c'))
>
>> vfio_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr.c'))
>> vfio_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files(
>> 'pci-quirks.c',
>
Good idea, will do that!
On 12/3/26 23:44, Pierrick Bouvier wrote: > Because those functions use kvm specific types, they need to be isolated > in another source file. > This allows us to link kvm-helpers only in configurations with > CONFIG_KVM. > > Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> > --- > hw/vfio/helpers.c | 172 ------------------------------------- > hw/vfio/kvm-helpers.c | 192 ++++++++++++++++++++++++++++++++++++++++++ > hw/vfio/kvm-stubs.c | 27 ++++++ > hw/vfio/meson.build | 2 + > 4 files changed, 221 insertions(+), 172 deletions(-) > create mode 100644 hw/vfio/kvm-helpers.c > create mode 100644 hw/vfio/kvm-stubs.c Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
© 2016 - 2026 Red Hat, Inc.