|
|
218e99 |
From 3f6f409e0c66e7f67d8830ffce9576ca306853ff Mon Sep 17 00:00:00 2001
|
|
|
218e99 |
From: Alex Williamson <alex.williamson@redhat.com>
|
|
|
218e99 |
Date: Tue, 5 Nov 2013 17:51:11 +0100
|
|
|
218e99 |
Subject: [PATCH 21/25] vfio-pci: Make use of new KVM-VFIO device
|
|
|
218e99 |
|
|
|
218e99 |
RH-Author: Alex Williamson <alex.williamson@redhat.com>
|
|
|
218e99 |
Message-id: <20131105175111.19705.95280.stgit@bling.home>
|
|
|
218e99 |
Patchwork-id: 55443
|
|
|
218e99 |
O-Subject: [RHEL7 qemu-kvm PATCH 2/2] vfio-pci: Make use of new KVM-VFIO device
|
|
|
218e99 |
Bugzilla: 1025474
|
|
|
218e99 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
218e99 |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
218e99 |
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
218e99 |
|
|
|
218e99 |
Bugzilla: 1025474
|
|
|
218e99 |
Upstream: Posted - http://lists.nongnu.org/archive/html/qemu-devel/2013-11/msg00091.html
|
|
|
218e99 |
|
|
|
218e99 |
Add and remove groups from the KVM virtual VFIO device as we make
|
|
|
218e99 |
use of them. This allows KVM to optimize for performance and
|
|
|
218e99 |
correctness based on properties of the group.
|
|
|
218e99 |
|
|
|
218e99 |
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
|
|
|
218e99 |
---
|
|
|
218e99 |
hw/misc/vfio.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
218e99 |
1 file changed, 65 insertions(+)
|
|
|
218e99 |
|
|
|
218e99 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
218e99 |
---
|
|
|
218e99 |
hw/misc/vfio.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
218e99 |
1 files changed, 65 insertions(+), 0 deletions(-)
|
|
|
218e99 |
|
|
|
218e99 |
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
|
|
|
218e99 |
index 331ae5f..b7f213b 100644
|
|
|
218e99 |
--- a/hw/misc/vfio.c
|
|
|
218e99 |
+++ b/hw/misc/vfio.c
|
|
|
218e99 |
@@ -208,6 +208,15 @@ static QLIST_HEAD(, VFIOContainer)
|
|
|
218e99 |
static QLIST_HEAD(, VFIOGroup)
|
|
|
218e99 |
group_list = QLIST_HEAD_INITIALIZER(group_list);
|
|
|
218e99 |
|
|
|
218e99 |
+/*
|
|
|
218e99 |
+ * We have a single VFIO pseudo device per KVM VM. Once created it lives
|
|
|
218e99 |
+ * for the life of the VM. Closing the file descriptor only drops our
|
|
|
218e99 |
+ * reference to it and the device's reference to kvm. Therefore once
|
|
|
218e99 |
+ * initialized, this file descriptor is only released on QEMU exit and
|
|
|
218e99 |
+ * we'll re-use it should another vfio device be attached before then.
|
|
|
218e99 |
+ */
|
|
|
218e99 |
+static int vfio_kvm_device_fd = -1;
|
|
|
218e99 |
+
|
|
|
218e99 |
static void vfio_disable_interrupts(VFIODevice *vdev);
|
|
|
218e99 |
static uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len);
|
|
|
218e99 |
static void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr,
|
|
|
218e99 |
@@ -3033,6 +3042,59 @@ static void vfio_pci_reset_handler(void *opaque)
|
|
|
218e99 |
}
|
|
|
218e99 |
}
|
|
|
218e99 |
|
|
|
218e99 |
+static void vfio_kvm_device_add_group(VFIOGroup *group)
|
|
|
218e99 |
+{
|
|
|
218e99 |
+#ifdef CONFIG_KVM
|
|
|
218e99 |
+ struct kvm_device_attr attr = {
|
|
|
218e99 |
+ .group = KVM_DEV_VFIO_GROUP,
|
|
|
218e99 |
+ .attr = KVM_DEV_VFIO_GROUP_ADD,
|
|
|
218e99 |
+ .addr = (uint64_t)(unsigned long)&group->fd,
|
|
|
218e99 |
+ };
|
|
|
218e99 |
+
|
|
|
218e99 |
+ if (!kvm_enabled()) {
|
|
|
218e99 |
+ return;
|
|
|
218e99 |
+ }
|
|
|
218e99 |
+
|
|
|
218e99 |
+ if (vfio_kvm_device_fd < 0) {
|
|
|
218e99 |
+ struct kvm_create_device cd = {
|
|
|
218e99 |
+ .type = KVM_DEV_TYPE_VFIO,
|
|
|
218e99 |
+ };
|
|
|
218e99 |
+
|
|
|
218e99 |
+ if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) {
|
|
|
218e99 |
+ DPRINTF("KVM_CREATE_DEVICE: %m\n");
|
|
|
218e99 |
+ return;
|
|
|
218e99 |
+ }
|
|
|
218e99 |
+
|
|
|
218e99 |
+ vfio_kvm_device_fd = cd.fd;
|
|
|
218e99 |
+ }
|
|
|
218e99 |
+
|
|
|
218e99 |
+ if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
|
|
|
218e99 |
+ error_report("Failed to add group %d to KVM VFIO device: %m",
|
|
|
218e99 |
+ group->groupid);
|
|
|
218e99 |
+ }
|
|
|
218e99 |
+#endif
|
|
|
218e99 |
+}
|
|
|
218e99 |
+
|
|
|
218e99 |
+static void vfio_kvm_device_del_group(VFIOGroup *group)
|
|
|
218e99 |
+{
|
|
|
218e99 |
+#ifdef CONFIG_KVM
|
|
|
218e99 |
+ struct kvm_device_attr attr = {
|
|
|
218e99 |
+ .group = KVM_DEV_VFIO_GROUP,
|
|
|
218e99 |
+ .attr = KVM_DEV_VFIO_GROUP_DEL,
|
|
|
218e99 |
+ .addr = (uint64_t)(unsigned long)&group->fd,
|
|
|
218e99 |
+ };
|
|
|
218e99 |
+
|
|
|
218e99 |
+ if (vfio_kvm_device_fd < 0) {
|
|
|
218e99 |
+ return;
|
|
|
218e99 |
+ }
|
|
|
218e99 |
+
|
|
|
218e99 |
+ if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
|
|
|
218e99 |
+ error_report("Failed to remove group %d to KVM VFIO device: %m",
|
|
|
218e99 |
+ group->groupid);
|
|
|
218e99 |
+ }
|
|
|
218e99 |
+#endif
|
|
|
218e99 |
+}
|
|
|
218e99 |
+
|
|
|
218e99 |
static int vfio_connect_container(VFIOGroup *group)
|
|
|
218e99 |
{
|
|
|
218e99 |
VFIOContainer *container;
|
|
|
218e99 |
@@ -3181,6 +3243,8 @@ static VFIOGroup *vfio_get_group(int groupid)
|
|
|
218e99 |
|
|
|
218e99 |
QLIST_INSERT_HEAD(&group_list, group, next);
|
|
|
218e99 |
|
|
|
218e99 |
+ vfio_kvm_device_add_group(group);
|
|
|
218e99 |
+
|
|
|
218e99 |
return group;
|
|
|
218e99 |
}
|
|
|
218e99 |
|
|
|
218e99 |
@@ -3190,6 +3254,7 @@ static void vfio_put_group(VFIOGroup *group)
|
|
|
218e99 |
return;
|
|
|
218e99 |
}
|
|
|
218e99 |
|
|
|
218e99 |
+ vfio_kvm_device_del_group(group);
|
|
|
218e99 |
vfio_disconnect_container(group);
|
|
|
218e99 |
QLIST_REMOVE(group, next);
|
|
|
218e99 |
DPRINTF("vfio_put_group: close group->fd\n");
|
|
|
218e99 |
--
|
|
|
218e99 |
1.7.1
|
|
|
218e99 |
|