mirror of https://gitee.com/openkylin/libvirt.git
conf: new pci controller model "pcie-root-port"
This controller can be connected (at domain startup time only - not hotpluggable) only to a port on the pcie root complex ("pcie-root" in libvirt config), hence the new connect type VIR_PCI_CONNECT_TYPE_PCIE_ROOT. It provides a hotpluggable port that will accept any PCI or PCIe device. New attributes must be added to the controller <target> subelement for this - chassis and port are guest-visible option values that will be set by libvirt with values derived from the controller's index and pci address information.
This commit is contained in:
parent
408b100a06
commit
dce3b8beb3
|
@ -3031,10 +3031,11 @@
|
|||
<p>
|
||||
PCI controllers have an optional <code>model</code> attribute with
|
||||
possible values <code>pci-root</code>, <code>pcie-root</code>,
|
||||
<code>pci-bridge</code>, or <code>dmi-to-pci-bridge</code>.
|
||||
<code>pcie-root-port</code>, <code>pci-bridge</code>,
|
||||
or <code>dmi-to-pci-bridge</code>.
|
||||
(pci-root and pci-bridge <span class="since">since 1.0.5</span>,
|
||||
pcie-root and dmi-to-pci-bridge <span class="since">since
|
||||
1.1.2</span>)
|
||||
1.1.2</span>, pcie-root-port <span class="since">since 1.2.19</span>)
|
||||
The root controllers (<code>pci-root</code> and <code>pcie-root</code>)
|
||||
have an optional <code>pcihole64</code> element specifying how big
|
||||
(in kilobytes, or in the unit specified by <code>pcihole64</code>'s
|
||||
|
@ -3079,6 +3080,23 @@
|
|||
the index attribute of the pci controller). If set, chassisNr
|
||||
must be between 0 and 255.
|
||||
</dd>
|
||||
<dt><code>chassis</code></dt>
|
||||
<dd>
|
||||
pcie-root-port controllers can also have
|
||||
a <code>chassis</code> attribute in
|
||||
the <code><target></code> subelement, which is used to
|
||||
set the controller's "chassis" configuration value, which is
|
||||
visible to the virtual machine. If set, chassis must be
|
||||
between 0 and 255.
|
||||
</dd>
|
||||
<dt><code>port</code></dt>
|
||||
<dd>
|
||||
pcie-root-port controllers can also have a <code>port</code>
|
||||
attribute in the <code><target></code> subelement, which
|
||||
is used to set the controller's "port" configuration value,
|
||||
which is visible to the virtual machine. If set, port must be
|
||||
between 0 and 255.
|
||||
</dd>
|
||||
</dl>
|
||||
<p>
|
||||
For machine types which provide an implicit PCI bus, the pci-root
|
||||
|
@ -3125,6 +3143,17 @@
|
|||
auto-determined by libvirt will be placed on this pci-bridge
|
||||
device. (<span class="since">since 1.1.2</span>).
|
||||
</p>
|
||||
<p>
|
||||
Domains with an implicit pcie-root can also add controllers
|
||||
with <code>model='pcie-root-port'</code>. This is a simple type of
|
||||
bridge device that can connect only to one of the 31 slots on
|
||||
the pcie-root bus on the upstream side, and makes a single
|
||||
(PCIe, hotpluggable) port (at slot='0') available on the
|
||||
downstream side. This controller can be used to provide a single
|
||||
slot to later hotplug a PCIe device (but is not itself
|
||||
hotpluggable - it must be in the configuration when the domain
|
||||
is started). (<span class="since">since 1.2.19</span>)
|
||||
</p>
|
||||
<pre>
|
||||
...
|
||||
<devices>
|
||||
|
|
|
@ -1739,6 +1739,8 @@
|
|||
<value>pci-bridge</value>
|
||||
<!-- implementations of 'dmi-to-pci-bridge' -->
|
||||
<value>i82801b11-bridge</value>
|
||||
<!-- implementations of 'pcie-root-port' -->
|
||||
<value>ioh3420</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
<empty/>
|
||||
|
@ -1751,6 +1753,16 @@
|
|||
<ref name='uint8range'/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="chassis">
|
||||
<ref name='uint8range'/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="port">
|
||||
<ref name='uint8range'/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
|
@ -1774,6 +1786,7 @@
|
|||
<choice>
|
||||
<value>pci-bridge</value>
|
||||
<value>dmi-to-pci-bridge</value>
|
||||
<value>pcie-root-port</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</group>
|
||||
|
|
|
@ -183,9 +183,9 @@ virDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus,
|
|||
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
|
||||
* attached also allows it.
|
||||
*/
|
||||
bus->flags = VIR_PCI_CONNECT_TYPE_PCIE;
|
||||
bus->flags = VIR_PCI_CONNECT_TYPE_PCIE | VIR_PCI_CONNECT_TYPE_PCIE_ROOT;
|
||||
bus->minSlot = 1;
|
||||
bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
|
||||
break;
|
||||
|
@ -196,6 +196,12 @@ virDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus,
|
|||
bus->minSlot = 1;
|
||||
bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
|
||||
break;
|
||||
case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT:
|
||||
/* provides one slot which is pcie and hotpluggable */
|
||||
bus->flags = VIR_PCI_CONNECT_TYPE_PCIE | VIR_PCI_CONNECT_HOTPLUGGABLE;
|
||||
bus->minSlot = 0;
|
||||
bus->maxSlot = 0;
|
||||
break;
|
||||
default:
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Invalid PCI controller model %d"), model);
|
||||
|
|
|
@ -39,6 +39,8 @@ typedef enum {
|
|||
/* 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_PCIE_ROOT = 1 << 4,
|
||||
/* for devices that can only connect to pcie-root (i.e. root-port) */
|
||||
} virDomainPCIConnectFlags;
|
||||
|
||||
typedef struct {
|
||||
|
@ -70,7 +72,8 @@ typedef virDomainPCIAddressSet *virDomainPCIAddressSetPtr;
|
|||
* allowed, e.g. PCI, PCIe, switch
|
||||
*/
|
||||
# define VIR_PCI_CONNECT_TYPES_MASK \
|
||||
(VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE)
|
||||
(VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE | \
|
||||
VIR_PCI_CONNECT_TYPE_PCIE_ROOT)
|
||||
|
||||
/* combination of all bits that could be used to connect a normal
|
||||
* endpoint device (i.e. excluding the connection possible between an
|
||||
|
|
|
@ -324,13 +324,15 @@ VIR_ENUM_IMPL(virDomainControllerModelPCI, VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST,
|
|||
"pci-root",
|
||||
"pcie-root",
|
||||
"pci-bridge",
|
||||
"dmi-to-pci-bridge")
|
||||
"dmi-to-pci-bridge",
|
||||
"pcie-root-port")
|
||||
|
||||
VIR_ENUM_IMPL(virDomainControllerPCIModelName,
|
||||
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST,
|
||||
"none",
|
||||
"pci-bridge",
|
||||
"i82801b11-bridge")
|
||||
"i82801b11-bridge",
|
||||
"ioh3420")
|
||||
|
||||
VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
|
||||
"auto",
|
||||
|
@ -1552,6 +1554,8 @@ virDomainControllerDefNew(virDomainControllerType type)
|
|||
break;
|
||||
case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
|
||||
def->opts.pciopts.chassisNr = -1;
|
||||
def->opts.pciopts.chassis = -1;
|
||||
def->opts.pciopts.port = -1;
|
||||
break;
|
||||
case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
|
||||
case VIR_DOMAIN_CONTROLLER_TYPE_FDC:
|
||||
|
@ -7814,6 +7818,8 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
|||
char *modelName = NULL;
|
||||
bool processedTarget = false;
|
||||
char *chassisNr = NULL;
|
||||
char *chassis = NULL;
|
||||
char *port = NULL;
|
||||
xmlNodePtr saved = ctxt->node;
|
||||
int rc;
|
||||
|
||||
|
@ -7874,6 +7880,8 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
|||
goto error;
|
||||
}
|
||||
chassisNr = virXMLPropString(cur, "chassisNr");
|
||||
chassis = virXMLPropString(cur, "chassis");
|
||||
port = virXMLPropString(cur, "port");
|
||||
processedTarget = true;
|
||||
}
|
||||
}
|
||||
|
@ -8008,6 +8016,40 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
|||
goto error;
|
||||
}
|
||||
}
|
||||
if (chassis) {
|
||||
if (virStrToLong_i(chassis, NULL, 0,
|
||||
&def->opts.pciopts.chassis) < 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("Invalid chassis '%s' in PCI controller"),
|
||||
chassis);
|
||||
goto error;
|
||||
}
|
||||
if (def->opts.pciopts.chassis < 0 ||
|
||||
def->opts.pciopts.chassis > 255) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("PCI controller chassis '%s' out of range "
|
||||
"- must be 0-255"),
|
||||
chassis);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (port) {
|
||||
if (virStrToLong_i(port, NULL, 0,
|
||||
&def->opts.pciopts.port) < 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("Invalid port '%s' in PCI controller"),
|
||||
port);
|
||||
goto error;
|
||||
}
|
||||
if (def->opts.pciopts.port < 0 ||
|
||||
def->opts.pciopts.port > 255) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("PCI controller port '%s' out of range "
|
||||
"- must be 0-255"),
|
||||
port);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -8035,6 +8077,8 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
|||
VIR_FREE(max_sectors);
|
||||
VIR_FREE(modelName);
|
||||
VIR_FREE(chassisNr);
|
||||
VIR_FREE(chassis);
|
||||
VIR_FREE(port);
|
||||
|
||||
return def;
|
||||
|
||||
|
@ -19089,7 +19133,9 @@ virDomainControllerDefFormat(virBufferPtr buf,
|
|||
pcihole64 = true;
|
||||
if (def->opts.pciopts.modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE)
|
||||
pciModel = true;
|
||||
if (def->opts.pciopts.chassisNr != -1)
|
||||
if (def->opts.pciopts.chassisNr != -1 ||
|
||||
def->opts.pciopts.chassis != -1 ||
|
||||
def->opts.pciopts.port != -1)
|
||||
pciTarget = true;
|
||||
break;
|
||||
|
||||
|
@ -19119,6 +19165,12 @@ virDomainControllerDefFormat(virBufferPtr buf,
|
|||
if (def->opts.pciopts.chassisNr != -1)
|
||||
virBufferAsprintf(buf, " chassisNr='%d'",
|
||||
def->opts.pciopts.chassisNr);
|
||||
if (def->opts.pciopts.chassis != -1)
|
||||
virBufferAsprintf(buf, " chassis='%d'",
|
||||
def->opts.pciopts.chassis);
|
||||
if (def->opts.pciopts.port != -1)
|
||||
virBufferAsprintf(buf, " port='0x%x'",
|
||||
def->opts.pciopts.port);
|
||||
virBufferAddLit(buf, "/>\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -752,6 +752,7 @@ typedef enum {
|
|||
VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT,
|
||||
VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE,
|
||||
VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE,
|
||||
VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT,
|
||||
|
||||
VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST
|
||||
} virDomainControllerModelPCI;
|
||||
|
@ -760,6 +761,7 @@ typedef enum {
|
|||
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE,
|
||||
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCI_BRIDGE,
|
||||
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_I82801B11_BRIDGE,
|
||||
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_IOH3420,
|
||||
|
||||
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST
|
||||
} virDomainControllerPCIModelName;
|
||||
|
@ -820,7 +822,11 @@ struct _virDomainPCIControllerOpts {
|
|||
* compatibility.
|
||||
*/
|
||||
int chassisNr; /* used by pci-bridge, -1 == unspecified */
|
||||
};
|
||||
/* chassis & port used by
|
||||
* pcie-root-port/pcie-switch-downstream-port, -1 = unspecified */
|
||||
int chassis;
|
||||
int port;
|
||||
};
|
||||
|
||||
/* Stores the virtual disk controller configuration */
|
||||
struct _virDomainControllerDef {
|
||||
|
|
|
@ -2283,6 +2283,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
|
|||
if (options->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE)
|
||||
options->modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_I82801B11_BRIDGE;
|
||||
break;
|
||||
case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT:
|
||||
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
|
||||
case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
|
||||
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<domain type='qemu'>
|
||||
<name>q35-test</name>
|
||||
<uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid>
|
||||
<memory unit='KiB'>2097152</memory>
|
||||
<currentMemory unit='KiB'>2097152</currentMemory>
|
||||
<vcpu placement='static' cpuset='0-1'>2</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64' machine='q35'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/libexec/qemu-kvm</emulator>
|
||||
<disk type='block' device='disk'>
|
||||
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||
<target dev='sda' bus='sata'/>
|
||||
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||
</disk>
|
||||
<controller type='pci' index='0' model='pcie-root'/>
|
||||
<controller type='pci' index='1' model='dmi-to-pci-bridge'/>
|
||||
<controller type='pci' index='2' model='pci-bridge'/>
|
||||
<controller type='pci' index='3' model='pcie-root-port'/>
|
||||
<controller type='pci' index='4' model='pcie-root-port'>
|
||||
<model name='ioh3420'/>
|
||||
<target chassis='40' port='0x1a'/>
|
||||
</controller>
|
||||
<controller type='sata' index='0'/>
|
||||
<video>
|
||||
<model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
|
||||
</video>
|
||||
<memballoon model='none'/>
|
||||
</devices>
|
||||
</domain>
|
|
@ -567,6 +567,7 @@ mymain(void)
|
|||
DO_TEST_DIFFERENT("pci-autoadd-idx");
|
||||
DO_TEST_DIFFERENT("pcie-root");
|
||||
DO_TEST_DIFFERENT("q35");
|
||||
DO_TEST("pcie-root-port");
|
||||
|
||||
DO_TEST("hostdev-scsi-lsi");
|
||||
DO_TEST("hostdev-scsi-virtio-scsi");
|
||||
|
|
Loading…
Reference in New Issue