virPCIGetVirtualFunctionInfo;
virPCIGetVirtualFunctions;
virPCIIsVirtualFunction;
+virPCIStubDriverTypeFromString;
+virPCIStubDriverTypeToString;
# util/virpidfile.h
goto cleanup;
if (!driverName || STREQ(driverName, "xen")) {
- if (virPCIDeviceSetStubDriver(pci, "pciback") < 0)
- goto cleanup;
+ virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_XEN);
} else {
virReportError(VIR_ERR_INVALID_ARG,
_("unsupported driver name '%s'"), driverName);
"supported on this system"));
goto cleanup;
}
- if (virPCIDeviceSetStubDriver(pci, "vfio-pci") < 0)
- goto cleanup;
+ virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_VFIO);
} else if (STREQ(driverName, "kvm")) {
if (!legacy) {
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
"supported on this system"));
goto cleanup;
}
- if (virPCIDeviceSetStubDriver(pci, "pci-stub") < 0)
- goto cleanup;
+ virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_KVM);
} else {
virReportError(VIR_ERR_INVALID_ARG,
_("unknown driver name '%s'"), driverName);
}
virPCIDeviceSetManaged(dev, hostdev->managed);
- if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
- if (virPCIDeviceSetStubDriver(dev, "vfio-pci") < 0) {
- virObjectUnref(list);
- return NULL;
- }
- } else if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN) {
- if (virPCIDeviceSetStubDriver(dev, "pciback") < 0) {
- virObjectUnref(list);
- return NULL;
- }
- } else {
- if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0) {
- virObjectUnref(list);
- return NULL;
- }
- }
+
+ if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO)
+ virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_VFIO);
+ else if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN)
+ virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_XEN);
+ else
+ virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_KVM);
}
return list;
for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
bool strict_acs_check = !!(flags & VIR_HOSTDEV_STRICT_ACS_CHECK);
- bool usesVfio = STREQ(virPCIDeviceGetStubDriver(dev), "vfio-pci");
+ bool usesVfio = (virPCIDeviceGetStubDriver(dev) == VIR_PCI_STUB_DRIVER_VFIO);
struct virHostdevIsPCINodeDeviceUsedData data = {hostdev_mgr, dom_name,
usesVfio};
}
/* Wait for device cleanup if it is qemu/kvm */
- if (STREQ(virPCIDeviceGetStubDriver(dev), "pci-stub")) {
+ if (virPCIDeviceGetStubDriver(dev) == VIR_PCI_STUB_DRIVER_KVM) {
int retries = 100;
while (virPCIDeviceWaitForCleanup(dev, "kvm_assigned_device")
&& retries) {
goto cleanup;
virPCIDeviceSetManaged(dev, hostdev->managed);
- if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
- if (virPCIDeviceSetStubDriver(dev, "vfio-pci") < 0)
- goto cleanup;
- } else if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN) {
- if (virPCIDeviceSetStubDriver(dev, "pciback") < 0)
- goto cleanup;
- } else {
- if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0)
- goto cleanup;
-
- }
virPCIDeviceSetUsedBy(dev, drv_name, dom_name);
+ if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO)
+ virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_VFIO);
+ else if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN)
+ virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_XEN);
+ else
+ virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_KVM);
+
/* Setup the original states for the PCI device */
virPCIDeviceSetUnbindFromStub(dev, hostdev->origstates.states.pci.unbind_from_stub);
virPCIDeviceSetRemoveSlot(dev, hostdev->origstates.states.pci.remove_slot);
VIR_ENUM_IMPL(virPCIELinkSpeed, VIR_PCIE_LINK_SPEED_LAST,
"", "2.5", "5", "8")
+VIR_ENUM_IMPL(virPCIStubDriver, VIR_PCI_STUB_DRIVER_LAST,
+ "none",
+ "pciback", /* XEN */
+ "pci-stub", /* KVM */
+ "vfio-pci", /* VFIO */
+);
+
struct _virPCIDevice {
virPCIDeviceAddress address;
bool has_flr;
bool has_pm_reset;
bool managed;
- char *stubDriver;
+
+ virPCIStubDriver stubDriver;
/* used by reattach function */
bool unbind_from_stub;
if (virPCIDeviceGetDriverPathAndName(dev, &drvPath, &drvName) < 0)
goto cleanup;
- if (STREQ_NULLABLE(drvName, "vfio-pci")) {
+ if (virPCIStubDriverTypeFromString(drvName) == VIR_PCI_STUB_DRIVER_VFIO) {
VIR_DEBUG("Device %s is bound to vfio-pci - skip reset",
dev->name);
ret = 0;
static int
-virPCIProbeStubDriver(const char *driver)
+virPCIProbeStubDriver(virPCIStubDriver driver)
{
+ const char *drvname = NULL;
char *drvpath = NULL;
bool probed = false;
+ if (driver == VIR_PCI_STUB_DRIVER_NONE ||
+ !(drvname = virPCIStubDriverTypeToString(driver))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s",
+ _("Attempting to use unknown stub driver"));
+ return -1;
+ }
+
recheck:
- if ((drvpath = virPCIDriverDir(driver)) && virFileExists(drvpath)) {
+ if ((drvpath = virPCIDriverDir(drvname)) && virFileExists(drvpath)) {
/* driver already loaded, return */
VIR_FREE(drvpath);
return 0;
if (!probed) {
char *errbuf = NULL;
probed = true;
- if ((errbuf = virKModLoad(driver, true))) {
- VIR_WARN("failed to load driver %s: %s", driver, errbuf);
+ if ((errbuf = virKModLoad(drvname, true))) {
+ VIR_WARN("failed to load driver %s: %s", drvname, errbuf);
VIR_FREE(errbuf);
goto cleanup;
}
/* If we know failure was because of blacklist, let's report that;
* otherwise, report a more generic failure message
*/
- if (virKModIsBlacklisted(driver)) {
+ if (virKModIsBlacklisted(drvname)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to load PCI stub module %s: "
"administratively prohibited"),
- driver);
+ drvname);
} else {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to load PCI stub module %s"),
- driver);
+ drvname);
}
return -1;
return ret;
}
-static const char *virPCIKnownStubs[] = {
- "pciback", /* used by xen */
- "pci-stub", /* used by kvm legacy passthrough */
- "vfio-pci", /* used by VFIO device assignment */
- NULL
-};
-
static int
virPCIDeviceUnbindFromStub(virPCIDevicePtr dev)
{
char *drvdir = NULL;
char *path = NULL;
char *driver = NULL;
- const char **stubTest;
- bool isStub = false;
/* If the device is currently bound to one of the "well known"
* stub drivers, then unbind it, otherwise ignore it.
goto remove_slot;
/* If the device isn't bound to a known stub, skip the unbind. */
- for (stubTest = virPCIKnownStubs; *stubTest != NULL; stubTest++) {
- if (STREQ(driver, *stubTest)) {
- isStub = true;
- VIR_DEBUG("Found stub driver %s", *stubTest);
- break;
- }
- }
- if (!isStub)
+ if (virPCIStubDriverTypeFromString(driver) < 0 ||
+ virPCIStubDriverTypeFromString(driver) == VIR_PCI_STUB_DRIVER_NONE)
goto remove_slot;
+ VIR_DEBUG("Found stub driver %s", driver);
+
if (virPCIDeviceUnbind(dev) < 0)
goto cleanup;
dev->unbind_from_stub = false;
char *stubDriverPath = NULL;
char *driverLink = NULL;
char *path = NULL; /* reused for different purposes */
- char *stubDriverName = dev->stubDriver;
+ const char *stubDriverName = NULL;
virErrorPtr err = NULL;
+ /* Check the device is configured to use one of the known stub drivers */
+ if (dev->stubDriver == VIR_PCI_STUB_DRIVER_NONE) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("No stub driver configured for PCI device %s"),
+ dev->name);
+ return -1;
+ } else if (!(stubDriverName = virPCIStubDriverTypeToString(dev->stubDriver))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unknown stub driver configured for PCI device %s"),
+ dev->name);
+ return -1;
+ }
+
if (!(stubDriverPath = virPCIDriverDir(stubDriverName)) ||
!(driverLink = virPCIFile(dev->name, "driver")))
goto cleanup;
virPCIDeviceList *activeDevs,
virPCIDeviceList *inactiveDevs)
{
- sa_assert(dev->stubDriver);
-
if (virPCIProbeStubDriver(dev->stubDriver) < 0)
return -1;
/* shallow copy to take care of most attributes */
*copy = *dev;
- copy->path = copy->stubDriver = NULL;
+ copy->path = NULL;
copy->used_by_drvname = copy->used_by_domname = NULL;
if (VIR_STRDUP(copy->path, dev->path) < 0 ||
- VIR_STRDUP(copy->stubDriver, dev->stubDriver) < 0 ||
VIR_STRDUP(copy->used_by_drvname, dev->used_by_drvname) < 0 ||
VIR_STRDUP(copy->used_by_domname, dev->used_by_domname) < 0) {
goto error;
return;
VIR_DEBUG("%s %s: freeing", dev->id, dev->name);
VIR_FREE(dev->path);
- VIR_FREE(dev->stubDriver);
VIR_FREE(dev->used_by_drvname);
VIR_FREE(dev->used_by_domname);
VIR_FREE(dev);
return dev->managed;
}
-int
-virPCIDeviceSetStubDriver(virPCIDevicePtr dev, const char *driver)
+void
+virPCIDeviceSetStubDriver(virPCIDevicePtr dev, virPCIStubDriver driver)
{
- VIR_FREE(dev->stubDriver);
- return VIR_STRDUP(dev->stubDriver, driver);
+ dev->stubDriver = driver;
}
-const char *
+virPCIStubDriver
virPCIDeviceGetStubDriver(virPCIDevicePtr dev)
{
return dev->stubDriver;
unsigned int function;
};
+typedef enum {
+ VIR_PCI_STUB_DRIVER_NONE = 0,
+ VIR_PCI_STUB_DRIVER_XEN,
+ VIR_PCI_STUB_DRIVER_KVM,
+ VIR_PCI_STUB_DRIVER_VFIO,
+ VIR_PCI_STUB_DRIVER_LAST
+} virPCIStubDriver;
+
+VIR_ENUM_DECL(virPCIStubDriver);
+
typedef enum {
VIR_PCIE_LINK_SPEED_NA = 0,
VIR_PCIE_LINK_SPEED_25,
void virPCIDeviceSetManaged(virPCIDevice *dev,
bool managed);
unsigned int virPCIDeviceGetManaged(virPCIDevice *dev);
-int virPCIDeviceSetStubDriver(virPCIDevicePtr dev,
- const char *driver)
- ATTRIBUTE_NONNULL(2);
-const char *virPCIDeviceGetStubDriver(virPCIDevicePtr dev);
+void virPCIDeviceSetStubDriver(virPCIDevicePtr dev,
+ virPCIStubDriver driver);
+virPCIStubDriver virPCIDeviceGetStubDriver(virPCIDevicePtr dev);
virPCIDeviceAddressPtr virPCIDeviceGetAddress(virPCIDevicePtr dev);
int virPCIDeviceSetUsedBy(virPCIDevice *dev,
const char *drv_name,
return -1;
if (!driverName) {
- if (virPCIDeviceSetStubDriver(pci, "pciback") < 0)
- goto out;
+ virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_XEN);
} else {
virReportError(VIR_ERR_INVALID_ARG,
_("unknown driver name '%s'"), driverName);
}
for (i = 0; i < nhostdevs; i++) {
- if (!(dev[i] = virPCIDeviceNew(0, 0, i + 1, 0)) ||
- virPCIDeviceSetStubDriver(dev[i], "pci-stub") < 0)
+ if (!(dev[i] = virPCIDeviceNew(0, 0, i + 1, 0)))
goto cleanup;
+
+ virPCIDeviceSetStubDriver(dev[i], VIR_PCI_STUB_DRIVER_KVM);
}
if (VIR_ALLOC(mgr) < 0)
CHECK_LIST_COUNT(inactiveDevs, 0);
for (i = 0; i < nDev; i++) {
- if (!(dev[i] = virPCIDeviceNew(0, 0, i + 1, 0)) ||
- virPCIDeviceSetStubDriver(dev[i], "pci-stub") < 0)
+ if (!(dev[i] = virPCIDeviceNew(0, 0, i + 1, 0)))
goto cleanup;
+ virPCIDeviceSetStubDriver(dev[i], VIR_PCI_STUB_DRIVER_KVM);
+
if (virPCIDeviceDetach(dev[i], activeDevs, inactiveDevs) < 0)
goto cleanup;
CHECK_LIST_COUNT(inactiveDevs, 0);
for (i = 0; i < nDev; i++) {
- if (!(dev[i] = virPCIDeviceNew(0, 0, i + 1, 0)) ||
- virPCIDeviceSetStubDriver(dev[i], "pci-stub") < 0)
+ if (!(dev[i] = virPCIDeviceNew(0, 0, i + 1, 0)))
goto cleanup;
+ virPCIDeviceSetStubDriver(dev[i], VIR_PCI_STUB_DRIVER_KVM);
+
if (virPCIDeviceReset(dev[i], activeDevs, inactiveDevs) < 0)
goto cleanup;
}
CHECK_LIST_COUNT(activeDevs, 0);
CHECK_LIST_COUNT(inactiveDevs, i + 1);
- if (virPCIDeviceSetStubDriver(dev[i], "pci-stub") < 0)
- goto cleanup;
+ virPCIDeviceSetStubDriver(dev[i], VIR_PCI_STUB_DRIVER_KVM);
}
CHECK_LIST_COUNT(activeDevs, 0);
if (!dev)
goto cleanup;
- if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0 ||
- virPCIDeviceDetach(dev, NULL, NULL) < 0)
+ virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_KVM);
+
+ if (virPCIDeviceDetach(dev, NULL, NULL) < 0)
goto cleanup;
ret = 0;
if (!dev)
goto cleanup;
- if (virPCIDeviceSetStubDriver(dev, "vfio-pci") < 0)
- goto cleanup;
+ virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_VFIO);
if (virPCIDeviceDetach(dev, NULL, NULL) < 0) {
if (virTestGetVerbose() || virTestGetDebug())
virReportError(VIR_ERR_INTERNAL_ERROR,
"Attaching device %s to %s should have failed",
virPCIDeviceGetName(dev),
- virPCIDeviceGetStubDriver(dev));
+ virPCIStubDriverTypeToString(VIR_PCI_STUB_DRIVER_VFIO));
}
cleanup: