|
|
7a3408 |
From ceeaf62ea52df6cfacac8c1653ff9f7585ef0392 Mon Sep 17 00:00:00 2001
|
|
|
7a3408 |
Message-Id: <ceeaf62ea52df6cfacac8c1653ff9f7585ef0392@dist-git>
|
|
|
7a3408 |
From: Shivaprasad G Bhat <shivaprasadbhat@gmail.com>
|
|
|
7a3408 |
Date: Wed, 2 Sep 2015 15:55:23 -0400
|
|
|
7a3408 |
Subject: [PATCH] Allow vfio hotplug of a device to the domain which owns the
|
|
|
7a3408 |
iommu
|
|
|
7a3408 |
|
|
|
7a3408 |
The commit 7e72de4 didn't consider the hotplug scenarios. The patch addresses
|
|
|
7a3408 |
the hotplug case whereby if atleast one of the pci function is owned by a
|
|
|
7a3408 |
guest, the hotplug of other functions/devices in the same iommu group to the
|
|
|
7a3408 |
same guest goes through successfully.
|
|
|
7a3408 |
|
|
|
7a3408 |
Prerequisite for the fix for:
|
|
|
7a3408 |
|
|
|
7a3408 |
https://bugzilla.redhat.com/show_bug.cgi?id=1256486
|
|
|
7a3408 |
|
|
|
7a3408 |
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.vnet.ibm.com>
|
|
|
7a3408 |
(cherry picked from commit e3810db34f1acb74dfcfd69219930e23a30284f6)
|
|
|
7a3408 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
---
|
|
|
7a3408 |
src/util/virhostdev.c | 34 +++++++++++++++++++++++++++-------
|
|
|
7a3408 |
1 file changed, 27 insertions(+), 7 deletions(-)
|
|
|
7a3408 |
|
|
|
7a3408 |
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
|
|
|
7a3408 |
index 809caed..529753c 100644
|
|
|
7a3408 |
--- a/src/util/virhostdev.c
|
|
|
7a3408 |
+++ b/src/util/virhostdev.c
|
|
|
7a3408 |
@@ -54,23 +54,35 @@ static virClassPtr virHostdevManagerClass;
|
|
|
7a3408 |
static void virHostdevManagerDispose(void *obj);
|
|
|
7a3408 |
static virHostdevManagerPtr virHostdevManagerNew(void);
|
|
|
7a3408 |
|
|
|
7a3408 |
+struct virHostdevIsPCINodeDeviceUsedData {
|
|
|
7a3408 |
+ virHostdevManagerPtr hostdev_mgr;
|
|
|
7a3408 |
+ const char *domainName;
|
|
|
7a3408 |
+ const bool usesVfio;
|
|
|
7a3408 |
+};
|
|
|
7a3408 |
+
|
|
|
7a3408 |
static int virHostdevIsPCINodeDeviceUsed(virPCIDeviceAddressPtr devAddr, void *opaque)
|
|
|
7a3408 |
{
|
|
|
7a3408 |
virPCIDevicePtr other;
|
|
|
7a3408 |
int ret = -1;
|
|
|
7a3408 |
virPCIDevicePtr pci = NULL;
|
|
|
7a3408 |
- virHostdevManagerPtr hostdev_mgr = opaque;
|
|
|
7a3408 |
+ struct virHostdevIsPCINodeDeviceUsedData *helperData = opaque;
|
|
|
7a3408 |
|
|
|
7a3408 |
if (!(pci = virPCIDeviceNew(devAddr->domain, devAddr->bus,
|
|
|
7a3408 |
devAddr->slot, devAddr->function)))
|
|
|
7a3408 |
goto cleanup;
|
|
|
7a3408 |
|
|
|
7a3408 |
- other = virPCIDeviceListFind(hostdev_mgr->activePCIHostdevs, pci);
|
|
|
7a3408 |
+ other = virPCIDeviceListFind(helperData->hostdev_mgr->activePCIHostdevs,
|
|
|
7a3408 |
+ pci);
|
|
|
7a3408 |
if (other) {
|
|
|
7a3408 |
const char *other_drvname = NULL;
|
|
|
7a3408 |
const char *other_domname = NULL;
|
|
|
7a3408 |
virPCIDeviceGetUsedBy(other, &other_drvname, &other_domname);
|
|
|
7a3408 |
|
|
|
7a3408 |
+ if (helperData->usesVfio &&
|
|
|
7a3408 |
+ (other_domname && helperData->domainName) &&
|
|
|
7a3408 |
+ (STREQ(other_domname, helperData->domainName)))
|
|
|
7a3408 |
+ goto iommu_owner;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
if (other_drvname && other_domname)
|
|
|
7a3408 |
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
7a3408 |
_("PCI device %s is in use by "
|
|
|
7a3408 |
@@ -83,6 +95,7 @@ static int virHostdevIsPCINodeDeviceUsed(virPCIDeviceAddressPtr devAddr, void *o
|
|
|
7a3408 |
virPCIDeviceGetName(pci));
|
|
|
7a3408 |
goto cleanup;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
+ iommu_owner:
|
|
|
7a3408 |
ret = 0;
|
|
|
7a3408 |
cleanup:
|
|
|
7a3408 |
virPCIDeviceFree(pci);
|
|
|
7a3408 |
@@ -562,6 +575,9 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
|
|
|
7a3408 |
for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
|
|
|
7a3408 |
virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
|
|
|
7a3408 |
bool strict_acs_check = !!(flags & VIR_HOSTDEV_STRICT_ACS_CHECK);
|
|
|
7a3408 |
+ bool usesVfio = STREQ(virPCIDeviceGetStubDriver(dev), "vfio-pci");
|
|
|
7a3408 |
+ struct virHostdevIsPCINodeDeviceUsedData data = {hostdev_mgr, dom_name,
|
|
|
7a3408 |
+ usesVfio};
|
|
|
7a3408 |
|
|
|
7a3408 |
if (!virPCIDeviceIsAssignable(dev, strict_acs_check)) {
|
|
|
7a3408 |
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
7a3408 |
@@ -579,12 +595,12 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
|
|
|
7a3408 |
* belonging to same iommu group can't be shared
|
|
|
7a3408 |
* across guests.
|
|
|
7a3408 |
*/
|
|
|
7a3408 |
- if (STREQ(virPCIDeviceGetStubDriver(dev), "vfio-pci")) {
|
|
|
7a3408 |
+ if (usesVfio) {
|
|
|
7a3408 |
if (virPCIDeviceAddressIOMMUGroupIterate(devAddr,
|
|
|
7a3408 |
virHostdevIsPCINodeDeviceUsed,
|
|
|
7a3408 |
- hostdev_mgr) < 0)
|
|
|
7a3408 |
+ &data) < 0)
|
|
|
7a3408 |
goto cleanup;
|
|
|
7a3408 |
- } else if (virHostdevIsPCINodeDeviceUsed(devAddr, hostdev_mgr)) {
|
|
|
7a3408 |
+ } else if (virHostdevIsPCINodeDeviceUsed(devAddr, &data)) {
|
|
|
7a3408 |
goto cleanup;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
}
|
|
|
7a3408 |
@@ -1544,6 +1560,8 @@ virHostdevPCINodeDeviceDetach(virHostdevManagerPtr hostdev_mgr,
|
|
|
7a3408 |
virPCIDevicePtr pci)
|
|
|
7a3408 |
{
|
|
|
7a3408 |
virPCIDeviceAddressPtr devAddr = NULL;
|
|
|
7a3408 |
+ struct virHostdevIsPCINodeDeviceUsedData data = { hostdev_mgr, NULL,
|
|
|
7a3408 |
+ false };
|
|
|
7a3408 |
int ret = -1;
|
|
|
7a3408 |
|
|
|
7a3408 |
virObjectLock(hostdev_mgr->activePCIHostdevs);
|
|
|
7a3408 |
@@ -1552,7 +1570,7 @@ virHostdevPCINodeDeviceDetach(virHostdevManagerPtr hostdev_mgr,
|
|
|
7a3408 |
if (!(devAddr = virPCIDeviceGetAddress(pci)))
|
|
|
7a3408 |
goto out;
|
|
|
7a3408 |
|
|
|
7a3408 |
- if (virHostdevIsPCINodeDeviceUsed(devAddr, hostdev_mgr))
|
|
|
7a3408 |
+ if (virHostdevIsPCINodeDeviceUsed(devAddr, &data))
|
|
|
7a3408 |
goto out;
|
|
|
7a3408 |
|
|
|
7a3408 |
if (virPCIDeviceDetach(pci, hostdev_mgr->activePCIHostdevs,
|
|
|
7a3408 |
@@ -1573,6 +1591,8 @@ virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr hostdev_mgr,
|
|
|
7a3408 |
virPCIDevicePtr pci)
|
|
|
7a3408 |
{
|
|
|
7a3408 |
virPCIDeviceAddressPtr devAddr = NULL;
|
|
|
7a3408 |
+ struct virHostdevIsPCINodeDeviceUsedData data = {hostdev_mgr, NULL,
|
|
|
7a3408 |
+ false};
|
|
|
7a3408 |
int ret = -1;
|
|
|
7a3408 |
|
|
|
7a3408 |
virObjectLock(hostdev_mgr->activePCIHostdevs);
|
|
|
7a3408 |
@@ -1581,7 +1601,7 @@ virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr hostdev_mgr,
|
|
|
7a3408 |
if (!(devAddr = virPCIDeviceGetAddress(pci)))
|
|
|
7a3408 |
goto out;
|
|
|
7a3408 |
|
|
|
7a3408 |
- if (virHostdevIsPCINodeDeviceUsed(devAddr, hostdev_mgr))
|
|
|
7a3408 |
+ if (virHostdevIsPCINodeDeviceUsed(devAddr, &data))
|
|
|
7a3408 |
goto out;
|
|
|
7a3408 |
|
|
|
7a3408 |
virPCIDeviceReattachInit(pci);
|
|
|
7a3408 |
--
|
|
|
7a3408 |
2.5.1
|
|
|
7a3408 |
|