c401cc
From 78d7cfd2e333001fb6b725052befc5c767a2e9a5 Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <78d7cfd2e333001fb6b725052befc5c767a2e9a5.1386348947.git.jdenemar@redhat.com>
c401cc
From: Laine Stump <laine@laine.org>
c401cc
Date: Tue, 3 Dec 2013 03:30:32 -0700
c401cc
Subject: [PATCH] qemu: default to vfio for nodedev-detach
c401cc
c401cc
This patch resolves:
c401cc
c401cc
  https://bugzilla.redhat.com/show_bug.cgi?id=1035188
c401cc
c401cc
Commit f094aaac48a6 changed the PCI device assignment in qemu domains
c401cc
to default to using VFIO rather than legacy KVM device assignment
c401cc
(when VFIO is available). It didn't change which driver was used by
c401cc
default for virNodeDeviceDetachFlags(), though, so that API (and the
c401cc
virsh nodedev-detach command) was still binding to the pci-stub
c401cc
driver, used by legacy KVM assignment, by default.
c401cc
c401cc
This patch publicizes (only within the qemu module, though, so no
c401cc
additions to the symbol exports are needed) the functions that check
c401cc
for presence of KVM and VFIO device assignment, then uses those
c401cc
functions to decide what to do when no driver is specified for
c401cc
virNodeDeviceDetachFlags(); if the vfio driver is loaded, the device
c401cc
will be bound to vfio-pci, or if legacy KVM assignment is supported on
c401cc
this system, the device will be bound to pci-stub; if neither method
c401cc
is available, the detach will fail.
c401cc
c401cc
(cherry picked from commit 47b9aae0ae0652738d3a65d6cdd6b0bb16b3a2ec)
c401cc
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 src/qemu/qemu_driver.c  | 19 ++++++++++++++++---
c401cc
 src/qemu/qemu_hostdev.c |  6 +++---
c401cc
 src/qemu/qemu_hostdev.h |  4 +++-
c401cc
 3 files changed, 22 insertions(+), 7 deletions(-)
c401cc
c401cc
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
c401cc
index e7b0f37..09345b1 100644
c401cc
--- a/src/qemu/qemu_driver.c
c401cc
+++ b/src/qemu/qemu_driver.c
c401cc
@@ -11005,12 +11005,25 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
c401cc
     if (!pci)
c401cc
         goto cleanup;
c401cc
 
c401cc
-    if (!driverName || STREQ(driverName, "kvm")) {
c401cc
-        if (virPCIDeviceSetStubDriver(pci, "pci-stub") < 0)
c401cc
-            goto cleanup;
c401cc
+    if (!driverName) {
c401cc
+        /* prefer vfio */
c401cc
+        if (qemuHostdevHostSupportsPassthroughVFIO())
c401cc
+            driverName = "vfio";
c401cc
+        else if (qemuHostdevHostSupportsPassthroughLegacy())
c401cc
+            driverName = "kvm";
c401cc
+    }
c401cc
+
c401cc
+    if (!driverName) {
c401cc
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
c401cc
+                       _("neither VFIO nor kvm device assignment is "
c401cc
+                         "currently supported on this system"));
c401cc
+        goto cleanup;
c401cc
     } else if (STREQ(driverName, "vfio")) {
c401cc
         if (virPCIDeviceSetStubDriver(pci, "vfio-pci") < 0)
c401cc
             goto cleanup;
c401cc
+    } else if (STREQ(driverName, "kvm")) {
c401cc
+        if (virPCIDeviceSetStubDriver(pci, "pci-stub") < 0)
c401cc
+            goto cleanup;
c401cc
     } else {
c401cc
         virReportError(VIR_ERR_INVALID_ARG,
c401cc
                        _("unknown driver name '%s'"), driverName);
c401cc
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
c401cc
index ca26dde..b78f080 100644
c401cc
--- a/src/qemu/qemu_hostdev.c
c401cc
+++ b/src/qemu/qemu_hostdev.c
c401cc
@@ -501,7 +501,7 @@ qemuDomainHostdevNetConfigRestore(virDomainHostdevDefPtr hostdev,
c401cc
 }
c401cc
 
c401cc
 
c401cc
-static bool
c401cc
+bool
c401cc
 qemuHostdevHostSupportsPassthroughVFIO(void)
c401cc
 {
c401cc
     DIR *iommuDir = NULL;
c401cc
@@ -541,7 +541,7 @@ cleanup:
c401cc
 
c401cc
 #if HAVE_LINUX_KVM_H
c401cc
 # include <linux/kvm.h>
c401cc
-static bool
c401cc
+bool
c401cc
 qemuHostdevHostSupportsPassthroughLegacy(void)
c401cc
 {
c401cc
     int kvmfd = -1;
c401cc
@@ -563,7 +563,7 @@ cleanup:
c401cc
     return ret;
c401cc
 }
c401cc
 #else
c401cc
-static bool
c401cc
+bool
c401cc
 qemuHostdevHostSupportsPassthroughLegacy(void)
c401cc
 {
c401cc
     return false;
c401cc
diff --git a/src/qemu/qemu_hostdev.h b/src/qemu/qemu_hostdev.h
c401cc
index 272086e..ffb3167 100644
c401cc
--- a/src/qemu/qemu_hostdev.h
c401cc
+++ b/src/qemu/qemu_hostdev.h
c401cc
@@ -1,7 +1,7 @@
c401cc
 /*
c401cc
  * qemu_hostdev.h: QEMU hostdev management
c401cc
  *
c401cc
- * Copyright (C) 2006-2007, 2009-2010 Red Hat, Inc.
c401cc
+ * Copyright (C) 2006-2007, 2009-2013 Red Hat, Inc.
c401cc
  * Copyright (C) 2006 Daniel P. Berrange
c401cc
  *
c401cc
  * This library is free software; you can redistribute it and/or
c401cc
@@ -33,6 +33,8 @@ int qemuUpdateActiveUsbHostdevs(virQEMUDriverPtr driver,
c401cc
                                 virDomainDefPtr def);
c401cc
 int qemuUpdateActiveScsiHostdevs(virQEMUDriverPtr driver,
c401cc
                                  virDomainDefPtr def);
c401cc
+bool qemuHostdevHostSupportsPassthroughLegacy(void);
c401cc
+bool qemuHostdevHostSupportsPassthroughVFIO(void);
c401cc
 int qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver,
c401cc
                                  const char *name,
c401cc
                                  const unsigned char *uuid,
c401cc
-- 
c401cc
1.8.4.5
c401cc