diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index e7b79579f91d184d2bcd1d3bb0f250105f9b3410..4e15d38463fe6a83ad31876f5fbdcc6206d26721 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -1,7 +1,7 @@ /* * device_conf.c: device XML handling * - * Copyright (C) 2006-2012 Red Hat, Inc. + * Copyright (C) 2006-2015 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -55,12 +55,49 @@ VIR_ENUM_IMPL(virNetDevFeature, "rdma", "txudptnl") -int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr) +int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr, + bool report) { - /* PCI bus has 32 slots and 8 functions per slot */ - if (addr->slot >= 32 || addr->function >= 8) + if (addr->domain > 0xFFFF) { + if (report) + virReportError(VIR_ERR_XML_ERROR, + _("Invalid PCI address domain='0x%x', " + "must be <= 0xFFFF"), + addr->domain); + return 0; + } + if (addr->bus > 0xFF) { + if (report) + virReportError(VIR_ERR_XML_ERROR, + _("Invalid PCI address bus='0x%x', " + "must be <= 0xFF"), + addr->bus); return 0; - return addr->domain || addr->bus || addr->slot; + } + if (addr->slot > 0x1F) { + if (report) + virReportError(VIR_ERR_XML_ERROR, + _("Invalid PCI address slot='0x%x', " + "must be <= 0x1F"), + addr->slot); + return 0; + } + if (addr->function > 7) { + if (report) + virReportError(VIR_ERR_XML_ERROR, + _("Invalid PCI address function=0x%x, " + "must be <= 7"), + addr->function); + return 0; + } + if (!(addr->domain || addr->bus || addr->slot)) { + if (report) + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Invalid PCI address 0000:00:00, at least " + "one of domain, bus, or slot must be > 0")); + return 0; + } + return 1; } @@ -115,11 +152,8 @@ virDevicePCIAddressParseXML(xmlNodePtr node, goto cleanup; } - if (!virDevicePCIAddressIsValid(addr)) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Insufficient specification for PCI address")); + if (!virDevicePCIAddressIsValid(addr, true)) goto cleanup; - } ret = 0; diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index 40a2b3df70a9e65a1e465e06bc8cd035cacb741a..85ce40f6831e766c8457bcc420de8d7b39c10d34 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -1,7 +1,7 @@ /* * device_conf.h: device XML handling entry points * - * Copyright (C) 2006-2012 Red Hat, Inc. + * Copyright (C) 2006-2012, 2014-2015 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -81,7 +81,8 @@ typedef enum { VIR_ENUM_DECL(virNetDevFeature) -int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr); +int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr, + bool report); int virDevicePCIAddressParseXML(xmlNodePtr node, virDevicePCIAddressPtr addr); diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e4114f8210484207ed158f3cbc9cf7974586c936..18e626985c2e62f5ad65d596a7672b465c07bfca 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3127,7 +3127,7 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, switch (info->type) { case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: - return virDevicePCIAddressIsValid(&info->addr.pci); + return virDevicePCIAddressIsValid(&info->addr.pci, false); case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: return 1; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pci-bus-invalid.xml b/tests/qemuxml2argvdata/qemuxml2argv-pci-bus-invalid.xml new file mode 100644 index 0000000000000000000000000000000000000000..f6d0901580b91e39b6e9452848e6e5b2f2f0bb85 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-pci-bus-invalid.xml @@ -0,0 +1,33 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + +
+ + + + + + + +
+ + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pci-domain-invalid.xml b/tests/qemuxml2argvdata/qemuxml2argv-pci-domain-invalid.xml new file mode 100644 index 0000000000000000000000000000000000000000..a42d796196207ef70a7381094f14d5980aa7af7a --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-pci-domain-invalid.xml @@ -0,0 +1,33 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + +
+ + + + + + + +
+ + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pci-function-invalid.xml b/tests/qemuxml2argvdata/qemuxml2argv-pci-function-invalid.xml new file mode 100644 index 0000000000000000000000000000000000000000..c9ba5a396273c6f0cf5c94a079c285214b40ac5a --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-pci-function-invalid.xml @@ -0,0 +1,33 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + +
+ + + + + + + +
+ + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pci-slot-invalid.xml b/tests/qemuxml2argvdata/qemuxml2argv-pci-slot-invalid.xml new file mode 100644 index 0000000000000000000000000000000000000000..09bab49a6558e4cd1a6259831985675512713fa7 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-pci-slot-invalid.xml @@ -0,0 +1,33 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + +
+ + + + + + + +
+ + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index afd2ef3a9884cbc035858e439be6ebb47b0b0cde..25f5aa692fb5b9b9a5f1ed1367d08602a02eec17 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1485,6 +1485,12 @@ mymain(void) DO_TEST_PARSE_ERROR("tpm-no-backend-invalid", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_TPM_PASSTHROUGH, QEMU_CAPS_DEVICE_TPM_TIS); + + DO_TEST_PARSE_ERROR("pci-domain-invalid", QEMU_CAPS_DEVICE); + DO_TEST_PARSE_ERROR("pci-bus-invalid", QEMU_CAPS_DEVICE); + DO_TEST_PARSE_ERROR("pci-slot-invalid", QEMU_CAPS_DEVICE); + DO_TEST_PARSE_ERROR("pci-function-invalid", QEMU_CAPS_DEVICE); + DO_TEST("pci-autoadd-addr", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE); DO_TEST("pci-autoadd-idx", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE); DO_TEST("pci-many",