diff --git a/src/Makefile.am b/src/Makefile.am index e9dc9e0df50900009f59b5863b1fd414dd678829..93baf18908f5a0559eb1d81b95b36663903f8179 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -247,6 +247,7 @@ NETDEV_CONF_SOURCES = \ # Domain driver generic impl APIs DOMAIN_CONF_SOURCES = \ conf/capabilities.c conf/capabilities.h \ + conf/domain_addr.h \ conf/domain_conf.c conf/domain_conf.h \ conf/domain_audit.c conf/domain_audit.h \ conf/domain_nwfilter.c conf/domain_nwfilter.h \ diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h new file mode 100644 index 0000000000000000000000000000000000000000..f5a5199af622b793155b17cc7d5c2c70691acb57 --- /dev/null +++ b/src/conf/domain_addr.h @@ -0,0 +1,79 @@ +/* + * domain_addr.h: helper APIs for managing domain device addresses + * + * Copyright (C) 2006-2014 Red Hat, Inc. + * Copyright (C) 2006 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + * Author: Daniel P. Berrange + */ + +#ifndef __DOMAIN_ADDR_H__ +# define __DOMAIN_ADDR_H__ + +# include "domain_conf.h" + +# define VIR_PCI_ADDRESS_SLOT_LAST 31 +# define VIR_PCI_ADDRESS_FUNCTION_LAST 7 + +typedef enum { + VIR_PCI_CONNECT_HOTPLUGGABLE = 1 << 0, + /* This bus supports hot-plug */ + VIR_PCI_CONNECT_SINGLESLOT = 1 << 1, + /* This "bus" has only a single downstream slot/port */ + + VIR_PCI_CONNECT_TYPE_PCI = 1 << 2, + /* PCI devices can connect to this bus */ + VIR_PCI_CONNECT_TYPE_PCIE = 1 << 3, + /* PCI Express devices can connect to this bus */ + VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG = 1 << 4, + /* PCI *and* PCIe devices allowed, if the address + * was specified in the config by the user + */ +} virDomainPCIConnectFlags; + +typedef struct { + virDomainControllerModelPCI model; + /* flags an min/max can be computed from model, but + * having them ready makes life easier. + */ + virDomainPCIConnectFlags flags; + size_t minSlot, maxSlot; /* usually 0,0 or 1,31 */ + /* Each bit in a slot represents one function on that slot. If the + * bit is set, that function is in use by a device. + */ + uint8_t slots[VIR_PCI_ADDRESS_SLOT_LAST + 1]; +} virDomainPCIAddressBus; +typedef virDomainPCIAddressBus *virDomainPCIAddressBusPtr; + +struct _virDomainPCIAddressSet { + virDomainPCIAddressBus *buses; + size_t nbuses; + virDevicePCIAddress lastaddr; + virDomainPCIConnectFlags lastFlags; + bool dryRun; /* on a dry run, new buses are auto-added + and addresses aren't saved in device infos */ +}; +typedef struct _virDomainPCIAddressSet virDomainPCIAddressSet; +typedef virDomainPCIAddressSet *virDomainPCIAddressSetPtr; + +/* a combination of all bit that describe the type of connections + * allowed, e.g. PCI, PCIe, switch + */ +# define VIR_PCI_CONNECT_TYPES_MASK \ + (VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE) + +#endif /* __DOMAIN_ADDR_H__ */ diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index dd8e40a6363e06df12b83cc767af9ea6119181e3..ebf17a8a7f49f54984b615a807407d04958e642d 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -39,6 +39,7 @@ #include "viruuid.h" #include "c-ctype.h" #include "domain_nwfilter.h" +#include "domain_addr.h" #include "domain_audit.h" #include "domain_conf.h" #include "snapshot_conf.h" @@ -1443,47 +1444,21 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def, return ret; } -#define QEMU_PCI_ADDRESS_SLOT_LAST 31 -#define QEMU_PCI_ADDRESS_FUNCTION_LAST 7 - -typedef struct { - virDomainControllerModelPCI model; - /* flags an min/max can be computed from model, but - * having them ready makes life easier. - */ - qemuDomainPCIConnectFlags flags; - size_t minSlot, maxSlot; /* usually 0,0 or 1,31 */ - /* Each bit in a slot represents one function on that slot. If the - * bit is set, that function is in use by a device. - */ - uint8_t slots[QEMU_PCI_ADDRESS_SLOT_LAST + 1]; -} qemuDomainPCIAddressBus; -typedef qemuDomainPCIAddressBus *qemuDomainPCIAddressBusPtr; - -struct _qemuDomainPCIAddressSet { - qemuDomainPCIAddressBus *buses; - size_t nbuses; - virDevicePCIAddress lastaddr; - qemuDomainPCIConnectFlags lastFlags; - bool dryRun; /* on a dry run, new buses are auto-added - and addresses aren't saved in device infos */ -}; - static bool qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr, const char *addrStr, - qemuDomainPCIConnectFlags busFlags, - qemuDomainPCIConnectFlags devFlags, + virDomainPCIConnectFlags busFlags, + virDomainPCIConnectFlags devFlags, bool reportError, bool fromConfig) { virErrorNumber errType = (fromConfig ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR); - qemuDomainPCIConnectFlags flagsMatchMask = QEMU_PCI_CONNECT_TYPES_MASK; + virDomainPCIConnectFlags flagsMatchMask = VIR_PCI_CONNECT_TYPES_MASK; if (fromConfig) - flagsMatchMask |= QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG; + flagsMatchMask |= VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG; /* If this bus doesn't allow the type of connection (PCI * vs. PCIe) required by the device, or if the device requires @@ -1491,13 +1466,13 @@ qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr, */ if (!(devFlags & busFlags & flagsMatchMask)) { if (reportError) { - if (devFlags & QEMU_PCI_CONNECT_TYPE_PCI) { + if (devFlags & VIR_PCI_CONNECT_TYPE_PCI) { virReportError(errType, _("PCI bus is not compatible with the device " "at %s. Device requires a standard PCI slot, " "which is not provided by bus %.4x:%.2x"), addrStr, addr->domain, addr->bus); - } else if (devFlags & QEMU_PCI_CONNECT_TYPE_PCIE) { + } else if (devFlags & VIR_PCI_CONNECT_TYPE_PCIE) { virReportError(errType, _("PCI bus is not compatible with the device " "at %s. Device requires a PCI Express slot, " @@ -1514,8 +1489,8 @@ qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr, } return false; } - if ((devFlags & QEMU_PCI_CONNECT_HOTPLUGGABLE) && - !(busFlags & QEMU_PCI_CONNECT_HOTPLUGGABLE)) { + if ((devFlags & VIR_PCI_CONNECT_HOTPLUGGABLE) && + !(busFlags & VIR_PCI_CONNECT_HOTPLUGGABLE)) { if (reportError) { virReportError(errType, _("PCI bus is not compatible with the device " @@ -1534,13 +1509,13 @@ qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr, * comparing the flags). */ static bool -qemuDomainPCIAddressValidate(qemuDomainPCIAddressSetPtr addrs, +qemuDomainPCIAddressValidate(virDomainPCIAddressSetPtr addrs, virDevicePCIAddressPtr addr, const char *addrStr, - qemuDomainPCIConnectFlags flags, + virDomainPCIConnectFlags flags, bool fromConfig) { - qemuDomainPCIAddressBusPtr bus; + virDomainPCIAddressBusPtr bus; virErrorNumber errType = (fromConfig ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR); @@ -1585,10 +1560,10 @@ qemuDomainPCIAddressValidate(qemuDomainPCIAddressSetPtr addrs, addrStr, bus->maxSlot); return false; } - if (addr->function > QEMU_PCI_ADDRESS_FUNCTION_LAST) { + if (addr->function > VIR_PCI_ADDRESS_FUNCTION_LAST) { virReportError(errType, _("Invalid PCI address %s. function must be <= %u"), - addrStr, QEMU_PCI_ADDRESS_FUNCTION_LAST); + addrStr, VIR_PCI_ADDRESS_FUNCTION_LAST); return false; } return true; @@ -1596,33 +1571,33 @@ qemuDomainPCIAddressValidate(qemuDomainPCIAddressSetPtr addrs, static int -qemuDomainPCIAddressBusSetModel(qemuDomainPCIAddressBusPtr bus, +qemuDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus, virDomainControllerModelPCI model) { switch (model) { case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: - bus->flags = (QEMU_PCI_CONNECT_HOTPLUGGABLE | - QEMU_PCI_CONNECT_TYPE_PCI); + bus->flags = (VIR_PCI_CONNECT_HOTPLUGGABLE | + VIR_PCI_CONNECT_TYPE_PCI); bus->minSlot = 1; - bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST; + bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST; break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: /* slots 1 - 31, no hotplug, PCIe only unless the address was * specified in user config *and* the particular device being * attached also allows it */ - bus->flags = (QEMU_PCI_CONNECT_TYPE_PCIE | - QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG); + bus->flags = (VIR_PCI_CONNECT_TYPE_PCIE | + VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG); bus->minSlot = 1; - bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST; + bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST; break; case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: /* slots 1 - 31, standard PCI slots, * but *not* hot-pluggable */ - bus->flags = QEMU_PCI_CONNECT_TYPE_PCI; + bus->flags = VIR_PCI_CONNECT_TYPE_PCI; bus->minSlot = 1; - bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST; + bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST; break; default: virReportError(VIR_ERR_INTERNAL_ERROR, @@ -1646,9 +1621,9 @@ qemuDomainPCIAddressBusSetModel(qemuDomainPCIAddressBusPtr bus, * >0 = number of buses added */ static int -qemuDomainPCIAddressSetGrow(qemuDomainPCIAddressSetPtr addrs, +qemuDomainPCIAddressSetGrow(virDomainPCIAddressSetPtr addrs, virDevicePCIAddressPtr addr, - qemuDomainPCIConnectFlags flags) + virDomainPCIConnectFlags flags) { int add; size_t i; @@ -1659,7 +1634,7 @@ qemuDomainPCIAddressSetGrow(qemuDomainPCIAddressSetPtr addrs, return 0; /* auto-grow only works when we're adding plain PCI devices */ - if (!(flags & QEMU_PCI_CONNECT_TYPE_PCI)) { + if (!(flags & VIR_PCI_CONNECT_TYPE_PCI)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot automatically add a new PCI bus for a " "device requiring a slot other than standard PCI.")); @@ -1702,13 +1677,13 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, virDomainDeviceInfoPtr info, void *opaque) { - qemuDomainPCIAddressSetPtr addrs = opaque; + virDomainPCIAddressSetPtr addrs = opaque; int ret = -1; virDevicePCIAddressPtr addr = &info->addr.pci; bool entireSlot; /* flags may be changed from default below */ - qemuDomainPCIConnectFlags flags = (QEMU_PCI_CONNECT_HOTPLUGGABLE | - QEMU_PCI_CONNECT_TYPE_PCI); + virDomainPCIConnectFlags flags = (VIR_PCI_CONNECT_HOTPLUGGABLE | + VIR_PCI_CONNECT_TYPE_PCI); if ((info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) || ((device->type == VIR_DOMAIN_DEVICE_HOSTDEV) && @@ -1732,13 +1707,13 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, /* pci-bridge needs a PCI slot, but it isn't * hot-pluggable, so it doesn't need a hot-pluggable slot. */ - flags = QEMU_PCI_CONNECT_TYPE_PCI; + flags = VIR_PCI_CONNECT_TYPE_PCI; break; case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: /* pci-bridge needs a PCIe slot, but it isn't * hot-pluggable, so it doesn't need a hot-pluggable slot. */ - flags = QEMU_PCI_CONNECT_TYPE_PCIE; + flags = VIR_PCI_CONNECT_TYPE_PCIE; break; default: break; @@ -1749,7 +1724,7 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, /* SATA controllers aren't hot-plugged, and can be put in * either a PCI or PCIe slot */ - flags = QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE; + flags = VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE; break; case VIR_DOMAIN_CONTROLLER_TYPE_USB: @@ -1763,14 +1738,14 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2: case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3: case VIR_DOMAIN_CONTROLLER_MODEL_USB_VT82C686B_UHCI: - flags = (QEMU_PCI_CONNECT_TYPE_PCI | - QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG); + flags = (VIR_PCI_CONNECT_TYPE_PCI | + VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG); break; case VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI: /* should this be PCIE-only? Or do we need to allow PCI * for backward compatibility? */ - flags = QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE; + flags = VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE; break; case VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI: case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI: @@ -1785,8 +1760,8 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, switch (device->data.sound->model) { case VIR_DOMAIN_SOUND_MODEL_ICH6: case VIR_DOMAIN_SOUND_MODEL_ICH9: - flags = (QEMU_PCI_CONNECT_TYPE_PCI | - QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG); + flags = (VIR_PCI_CONNECT_TYPE_PCI | + VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG); break; } break; @@ -1795,7 +1770,7 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, /* video cards aren't hot-plugged, and can be put in either a * PCI or PCIe slot */ - flags = QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE; + flags = VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE; break; } @@ -1827,7 +1802,7 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, * commandline, but that don't really care if a PCI bus * actually exists. */ if (addrs->nbuses > 0 && - !(addrs->buses[0].flags & QEMU_PCI_CONNECT_TYPE_PCI)) { + !(addrs->buses[0].flags & VIR_PCI_CONNECT_TYPE_PCI)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Bus 0 must be PCI for integrated PIIX3 " "USB or IDE controllers")); @@ -1868,7 +1843,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, virDomainObjPtr obj) { int ret = -1; - qemuDomainPCIAddressSetPtr addrs = NULL; + virDomainPCIAddressSetPtr addrs = NULL; qemuDomainObjPrivatePtr priv = NULL; if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { @@ -1876,7 +1851,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, int nbuses = 0; size_t i; int rv; - qemuDomainPCIConnectFlags flags = QEMU_PCI_CONNECT_TYPE_PCI; + virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCI; for (i = 0; i < def->ncontrollers; i++) { if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) { @@ -1901,7 +1876,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, goto cleanup; for (i = 1; i < addrs->nbuses; i++) { - qemuDomainPCIAddressBusPtr bus = &addrs->buses[i]; + virDomainPCIAddressBusPtr bus = &addrs->buses[i]; if ((rv = virDomainDefMaybeAddController( def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, @@ -1975,12 +1950,12 @@ int qemuDomainAssignAddresses(virDomainDefPtr def, } -qemuDomainPCIAddressSetPtr +virDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def, unsigned int nbuses, bool dryRun) { - qemuDomainPCIAddressSetPtr addrs; + virDomainPCIAddressSetPtr addrs; size_t i; if (VIR_ALLOC(addrs) < 0) @@ -2038,7 +2013,7 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def, /* * Check if the PCI slot is used by another device. */ -static bool qemuDomainPCIAddressSlotInUse(qemuDomainPCIAddressSetPtr addrs, +static bool qemuDomainPCIAddressSlotInUse(virDomainPCIAddressSetPtr addrs, virDevicePCIAddressPtr addr) { return !!addrs->buses[addr->bus].slots[addr->slot]; @@ -2055,15 +2030,15 @@ static bool qemuDomainPCIAddressSlotInUse(qemuDomainPCIAddressSetPtr addrs, * XML). */ int -qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs, +qemuDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, virDevicePCIAddressPtr addr, - qemuDomainPCIConnectFlags flags, + virDomainPCIConnectFlags flags, bool reserveEntireSlot, bool fromConfig) { int ret = -1; char *addrStr = NULL; - qemuDomainPCIAddressBusPtr bus; + virDomainPCIAddressBusPtr bus; virErrorNumber errType = (fromConfig ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR); @@ -2117,14 +2092,14 @@ qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs, int -qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs, +qemuDomainPCIAddressReserveSlot(virDomainPCIAddressSetPtr addrs, virDevicePCIAddressPtr addr, - qemuDomainPCIConnectFlags flags) + virDomainPCIConnectFlags flags) { return qemuDomainPCIAddressReserveAddr(addrs, addr, flags, true, false); } -int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs, +int qemuDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr addrs, virDomainDeviceInfoPtr dev) { int ret = -1; @@ -2134,8 +2109,8 @@ int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs, * function is only used for hot-plug, though, and hot-plug is * only supported for standard PCI devices, so we can safely use * the setting below */ - qemuDomainPCIConnectFlags flags = (QEMU_PCI_CONNECT_HOTPLUGGABLE | - QEMU_PCI_CONNECT_TYPE_PCI); + virDomainPCIConnectFlags flags = (VIR_PCI_CONNECT_HOTPLUGGABLE | + VIR_PCI_CONNECT_TYPE_PCI); if (!(addrStr = qemuDomainPCIAddressAsString(&dev->addr.pci))) goto cleanup; @@ -2166,7 +2141,7 @@ int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs, } -int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs, +int qemuDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs, virDevicePCIAddressPtr addr) { addrs->buses[addr->bus].slots[addr->slot] &= ~(1 << addr->function); @@ -2174,13 +2149,13 @@ int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs, } static int -qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs, +qemuDomainPCIAddressReleaseSlot(virDomainPCIAddressSetPtr addrs, virDevicePCIAddressPtr addr) { /* permit any kind of connection type in validation, since we * already had it, and are giving it back. */ - qemuDomainPCIConnectFlags flags = QEMU_PCI_CONNECT_TYPES_MASK; + virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPES_MASK; int ret = -1; char *addrStr = NULL; @@ -2197,7 +2172,7 @@ qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs, return ret; } -void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs) +void qemuDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs) { if (!addrs) return; @@ -2208,9 +2183,9 @@ void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs) static int -qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs, +qemuDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs, virDevicePCIAddressPtr next_addr, - qemuDomainPCIConnectFlags flags) + virDomainPCIConnectFlags flags) { /* default to starting the search for a free slot from * 0000:00:00.0 @@ -2241,7 +2216,7 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs, a.domain, a.bus); continue; } - for (; a.slot <= QEMU_PCI_ADDRESS_SLOT_LAST; a.slot++) { + for (; a.slot <= VIR_PCI_ADDRESS_SLOT_LAST; a.slot++) { if (!qemuDomainPCIAddressSlotInUse(addrs, &a)) goto success; @@ -2271,7 +2246,7 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs, a.domain, a.bus); continue; } - for (a.slot = 1; a.slot <= QEMU_PCI_ADDRESS_SLOT_LAST; a.slot++) { + for (a.slot = 1; a.slot <= VIR_PCI_ADDRESS_SLOT_LAST; a.slot++) { if (!qemuDomainPCIAddressSlotInUse(addrs, &a)) goto success; @@ -2296,9 +2271,9 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs, } int -qemuDomainPCIAddressReserveNextSlot(qemuDomainPCIAddressSetPtr addrs, +qemuDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs, virDomainDeviceInfoPtr dev, - qemuDomainPCIConnectFlags flags) + virDomainPCIConnectFlags flags) { virDevicePCIAddress addr; if (qemuDomainPCIAddressGetNextSlot(addrs, &addr, flags) < 0) @@ -2354,14 +2329,14 @@ qemuDomainReleaseDeviceAddress(virDomainObjPtr vm, static int qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def, virQEMUCapsPtr qemuCaps, - qemuDomainPCIAddressSetPtr addrs) + virDomainPCIAddressSetPtr addrs) { int ret = -1; size_t i; virDevicePCIAddress tmp_addr; bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); char *addrStr = NULL; - qemuDomainPCIConnectFlags flags = QEMU_PCI_CONNECT_HOTPLUGGABLE | QEMU_PCI_CONNECT_TYPE_PCI; + virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI; /* Verify that first IDE and USB controllers (if any) is on the PIIX3, fn 1 */ for (i = 0; i < def->ncontrollers; i++) { @@ -2507,14 +2482,14 @@ qemuDomainMachineIsI440FX(virDomainDefPtr def) static int qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, virQEMUCapsPtr qemuCaps, - qemuDomainPCIAddressSetPtr addrs) + virDomainPCIAddressSetPtr addrs) { int ret = -1; size_t i; virDevicePCIAddress tmp_addr; bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); char *addrStr = NULL; - qemuDomainPCIConnectFlags flags = QEMU_PCI_CONNECT_TYPE_PCIE; + virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCIE; for (i = 0; i < def->ncontrollers; i++) { switch (def->controllers[i]->type) { @@ -2690,10 +2665,10 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, int qemuAssignDevicePCISlots(virDomainDefPtr def, virQEMUCapsPtr qemuCaps, - qemuDomainPCIAddressSetPtr addrs) + virDomainPCIAddressSetPtr addrs) { size_t i, j; - qemuDomainPCIConnectFlags flags; + virDomainPCIConnectFlags flags; virDevicePCIAddress tmp_addr; if ((STRPREFIX(def->os.machine, "pc-0.") || @@ -2725,16 +2700,16 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, /* pci-bridge doesn't require hot-plug * (although it does provide hot-plug in its slots) */ - flags = QEMU_PCI_CONNECT_TYPE_PCI; + flags = VIR_PCI_CONNECT_TYPE_PCI; break; case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: /* dmi-to-pci-bridge requires a non-hotplug PCIe * slot */ - flags = QEMU_PCI_CONNECT_TYPE_PCIE; + flags = VIR_PCI_CONNECT_TYPE_PCIE; break; default: - flags = QEMU_PCI_CONNECT_HOTPLUGGABLE | QEMU_PCI_CONNECT_TYPE_PCI; + flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI; break; } if (qemuDomainPCIAddressReserveNextSlot(addrs, @@ -2744,7 +2719,7 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, } } - flags = QEMU_PCI_CONNECT_HOTPLUGGABLE | QEMU_PCI_CONNECT_TYPE_PCI; + flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI; for (i = 0; i < def->nfss; i++) { if (def->fss[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 45f29a0917e03e2db0a6b49312c0cbb4e9f03398..29da1ca03536e826ddf08a0155ade93be8f5f535 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -24,6 +24,7 @@ #ifndef __QEMU_COMMAND_H__ # define __QEMU_COMMAND_H__ +# include "domain_addr.h" # include "domain_conf.h" # include "vircommand.h" # include "capabilities.h" @@ -234,55 +235,33 @@ void qemuDomainReleaseDeviceAddress(virDomainObjPtr vm, virDomainDeviceInfoPtr info, const char *devstr); -typedef enum { - QEMU_PCI_CONNECT_HOTPLUGGABLE = 1 << 0, - /* This bus supports hot-plug */ - QEMU_PCI_CONNECT_SINGLESLOT = 1 << 1, - /* This "bus" has only a single downstream slot/port */ - - QEMU_PCI_CONNECT_TYPE_PCI = 1 << 2, - /* PCI devices can connect to this bus */ - QEMU_PCI_CONNECT_TYPE_PCIE = 1 << 3, - /* PCI Express devices can connect to this bus */ - QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG = 1 << 4, - /* PCI *and* PCIe devices allowed, if the address - * was specified in the config by the user - */ -} qemuDomainPCIConnectFlags; - -/* a combination of all bit that describe the type of connections - * allowed, e.g. PCI, PCIe, switch - */ -# define QEMU_PCI_CONNECT_TYPES_MASK \ - (QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE) - int qemuDomainAssignPCIAddresses(virDomainDefPtr def, virQEMUCapsPtr qemuCaps, virDomainObjPtr obj); -qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def, - unsigned int nbuses, - bool dryRun); -int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs, +virDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def, + unsigned int nbuses, + bool dryRun); +int qemuDomainPCIAddressReserveSlot(virDomainPCIAddressSetPtr addrs, virDevicePCIAddressPtr addr, - qemuDomainPCIConnectFlags flags); -int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs, + virDomainPCIConnectFlags flags); +int qemuDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, virDevicePCIAddressPtr addr, - qemuDomainPCIConnectFlags flags, + virDomainPCIConnectFlags flags, bool reserveEntireSlot, bool fromConfig); -int qemuDomainPCIAddressReserveNextSlot(qemuDomainPCIAddressSetPtr addrs, +int qemuDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs, virDomainDeviceInfoPtr dev, - qemuDomainPCIConnectFlags flags); -int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs, + virDomainPCIConnectFlags flags); +int qemuDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr addrs, virDomainDeviceInfoPtr dev); -int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs, +int qemuDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs, virDevicePCIAddressPtr addr); -void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs); +void qemuDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs); int qemuAssignDevicePCISlots(virDomainDefPtr def, virQEMUCapsPtr qemuCaps, - qemuDomainPCIAddressSetPtr addrs); + virDomainPCIAddressSetPtr addrs); int qemuDomainCCWAddressAssign(virDomainDeviceInfoPtr dev, qemuDomainCCWAddressSetPtr addrs, bool autoassign); diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index ab27f157b4891030f6b361fcd99ed72c43150f73..29b9e7c197c9f297f46a74625b4645de5cf9b114 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -26,6 +26,7 @@ # include "virthread.h" # include "vircgroup.h" +# include "domain_addr.h" # include "domain_conf.h" # include "snapshot_conf.h" # include "qemu_monitor.h" @@ -116,9 +117,6 @@ struct qemuDomainJobObj { bool asyncAbort; /* abort of async job requested */ }; -typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet; -typedef qemuDomainPCIAddressSet *qemuDomainPCIAddressSetPtr; - typedef void (*qemuDomainCleanupCallback)(virQEMUDriverPtr driver, virDomainObjPtr vm); typedef struct _qemuDomainCCWAddressSet qemuDomainCCWAddressSet; @@ -146,7 +144,7 @@ struct _qemuDomainObjPrivate { int nvcpupids; int *vcpupids; - qemuDomainPCIAddressSetPtr pciaddrs; + virDomainPCIAddressSetPtr pciaddrs; qemuDomainCCWAddressSetPtr ccwaddrs; int persistentAddrs;