Add speed/width target attributes for the generic PCIe root and switch
ports to set the link speed/width capability.

This useful when used with passthrough devices to make the in-guest
apparent bandwidth match the hardware bandwidth. This allows in-guest
software (such as NCCL) to make better decisions about whether to use
P2P transfers etc.

Signed-off-by: David Vrabel <[email protected]>
---
 docs/formatdomain.rst                         |  12 ++
 src/conf/domain_conf.c                        |  22 ++++
 src/conf/domain_conf.h                        |   3 +
 src/conf/schemas/domaincommon.rng             |  10 ++
 src/qemu/qemu_capabilities.c                  | 114 +++++++++---------
 src/qemu/qemu_capabilities.h                  | 112 ++++++++---------
 src/qemu/qemu_command.c                       |  46 +++++++
 src/qemu/qemu_validate.c                      |  81 +++++++++++++
 .../caps_11.1.0_x86_64.replies                |   4 +-
 .../caps_11.1.0_x86_64.xml                    |   2 +
 ...e-root-port-speed-width.x86_64-latest.args |  37 ++++++
 ...ie-root-port-speed-width.x86_64-latest.xml |  48 ++++++++
 .../pcie-root-port-speed-width.xml            |  23 ++++
 ...ream-port-model-generic.x86_64-latest.args |   2 +-
 ...tream-port-model-generic.x86_64-latest.xml |   2 +-
 ...e-switch-downstream-port-model-generic.xml |   2 +-
 ...ream-port-model-generic.x86_64-latest.args |   2 +-
 ...tream-port-model-generic.x86_64-latest.xml |   1 +
 ...cie-switch-upstream-port-model-generic.xml |   1 +
 tests/qemuxmlconftest.c                       |   1 +
 20 files changed, 411 insertions(+), 114 deletions(-)
 create mode 100644 
tests/qemuxmlconfdata/pcie-root-port-speed-width.x86_64-latest.args
 create mode 100644 
tests/qemuxmlconfdata/pcie-root-port-speed-width.x86_64-latest.xml
 create mode 100644 tests/qemuxmlconfdata/pcie-root-port-speed-width.xml

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 5a278f3717..15fcf7ca69 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -4624,6 +4624,18 @@ generated by libvirt. :since:`Since 1.2.19 (QEMU only)`.
    reserve more memory (in KiB) so that such PCI device can be hot plugged.
    For cold plugged PCI devices, the firmware will automatically reserve the
    correct amount of memory. :since:`Since 10.3.0`
+``speed``
+   pcie-root-port, pcie-switch-upstream-port, and
+   pcie-switch-downstream-port controllers can also have a ``speed`` attribute
+   in the ``<target>`` subelement, which controls the PCIe link speed 
capability
+   visible to the guest (in GT/s). Supported values are 2.5, 5, 8, 16, 32,
+   and 64. Defaults to the maximum supported by the selected model.
+``width``
+   pcie-root-port, pcie-switch-upstream-port, and
+   pcie-switch-downstream-port controllers can also have a ``width`` attribute
+   in the ``<target>`` subelement, which controls the PCIe link width (number 
of
+   lanes) capability visible to the guest. Supported values are 1, 2, 4, 8, 16,
+   and 32. Defaults to the maximum supported by the selected model.
 
 For machine types which provide an implicit PCI bus, the pci-root controller
 with index=0 is auto-added and required to use PCI devices. pci-root has no
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b9db849060..b1aa941de7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2593,6 +2593,8 @@ virDomainControllerDefNew(virDomainControllerType type)
         def->opts.pciopts.chassisNr = -1;
         def->opts.pciopts.chassis = -1;
         def->opts.pciopts.port = -1;
+        def->opts.pciopts.speed = -1;
+        def->opts.pciopts.width = -1;
         def->opts.pciopts.busNr = -1;
         def->opts.pciopts.targetIndex = -1;
         def->opts.pciopts.numaNode = -1;
@@ -9218,6 +9220,8 @@ virDomainControllerDefParseXML(virDomainXMLOption *xmlopt,
 
     if (ntargetNodes == 1) {
         if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
+            g_autofree char *speed = NULL;
+
             if (virXMLPropInt(targetNodes[0], "chassisNr", 0, 
VIR_XML_PROP_NONNEGATIVE,
                               &def->opts.pciopts.chassisNr,
                               def->opts.pciopts.chassisNr) < 0)
@@ -9233,6 +9237,20 @@ virDomainControllerDefParseXML(virDomainXMLOption 
*xmlopt,
                               def->opts.pciopts.port) < 0)
                 return NULL;
 
+            speed = virXMLPropString(targetNodes[0], "speed");
+            if (speed &&
+                (virStrToDouble(speed, NULL, &def->opts.pciopts.speed) < 0 ||
+                 def->opts.pciopts.speed <= 0)) {
+                virReportError(VIR_ERR_XML_ERROR, "%s",
+                               _("Invalid non-positive value for PCI 
controller link speed"));
+                return NULL;
+            }
+
+            if (virXMLPropInt(targetNodes[0], "width", 0, 
VIR_XML_PROP_NONNEGATIVE,
+                              &def->opts.pciopts.width,
+                              def->opts.pciopts.width) < 0)
+                return NULL;
+
             if (virXMLPropInt(targetNodes[0], "busNr", 0, 
VIR_XML_PROP_NONNEGATIVE,
                               &def->opts.pciopts.busNr,
                               def->opts.pciopts.busNr) < 0)
@@ -24934,6 +24952,10 @@ virDomainControllerDefFormatPCI(virBuffer *buf,
         virBufferAsprintf(&targetAttrBuf, " chassis='%d'", 
def->opts.pciopts.chassis);
     if (def->opts.pciopts.port != -1)
         virBufferAsprintf(&targetAttrBuf, " port='0x%x'", 
def->opts.pciopts.port);
+    if (def->opts.pciopts.speed > 0)
+        virBufferAsprintf(&targetAttrBuf, " speed='%g'", 
def->opts.pciopts.speed);
+    if (def->opts.pciopts.width != -1)
+        virBufferAsprintf(&targetAttrBuf, " width='%d'", 
def->opts.pciopts.width);
     if (def->opts.pciopts.busNr != -1)
         virBufferAsprintf(&targetAttrBuf, " busNr='%d'", 
def->opts.pciopts.busNr);
     if (def->opts.pciopts.targetIndex != -1)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 01213f2b14..d9e59af89e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -767,6 +767,9 @@ struct _virDomainPCIControllerOpts {
      * pcie-root-port/pcie-switch-downstream-port, -1 = unspecified */
     int chassis;
     int port;
+    /* speed & width used by pcie-root-port/pcie-switch-upstream-port, -1 = 
unspecified */
+    double speed;
+    int width;
     int busNr; /* used by pci-expander-bus, -1 == unspecified */
     int targetIndex; /* used by spapr-pci-host-bridge, -1 == unspecified */
     /* numaNode is a *subelement* of target (to match existing
diff --git a/src/conf/schemas/domaincommon.rng 
b/src/conf/schemas/domaincommon.rng
index b1740892e6..92f073a6ec 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -3101,6 +3101,16 @@
                       <ref name="uint8"/>
                     </attribute>
                   </optional>
+                  <optional>
+                    <attribute name="speed">
+                      <data type="double"/>
+                    </attribute>
+                  </optional>
+                  <optional>
+                    <attribute name="width">
+                      <ref name="uint8"/>
+                    </attribute>
+                  </optional>
                   <optional>
                     <attribute name="busNr">
                       <ref name="uint8"/>
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 091eb88729..b1b2f0e39c 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -584,198 +584,202 @@ VIR_ENUM_IMPL(virQEMUCaps,
               "pcie-root-port.hotplug", /* QEMU_CAPS_PCIE_ROOT_PORT_HOTPLUG */
 
               /* 365 */
+              "pcie-root-port.speed", /* QEMU_CAPS_PCIE_ROOT_PORT_SPEED */
+              "pcie-root-port.width", /* QEMU_CAPS_PCIE_ROOT_PORT_WIDTH */
               "aio.io_uring", /* QEMU_CAPS_AIO_IO_URING */
               "machine.pseries.cap-cfpc", /* 
X_QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC */
               "machine.pseries.cap-sbbc", /* 
X_QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC */
-              "machine.pseries.cap-ibs", /* 
X_QEMU_CAPS_MACHINE_PSERIES_CAP_IBS */
-              "tcg", /* QEMU_CAPS_TCG */
 
               /* 370 */
+              "machine.pseries.cap-ibs", /* 
X_QEMU_CAPS_MACHINE_PSERIES_CAP_IBS */
+              "tcg", /* QEMU_CAPS_TCG */
               "virtio-blk-pci.scsi.default.disabled", /* 
QEMU_CAPS_VIRTIO_BLK_SCSI_DEFAULT_DISABLED */
               "pvscsi", /* QEMU_CAPS_SCSI_PVSCSI */
               "cpu.migratable", /* QEMU_CAPS_CPU_MIGRATABLE */
-              "query-cpu-model-expansion.migratable", /* 
X_QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_MIGRATABLE */
-              "fw_cfg", /* X_QEMU_CAPS_FW_CFG */
 
               /* 375 */
+              "query-cpu-model-expansion.migratable", /* 
X_QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_MIGRATABLE */
+              "fw_cfg", /* X_QEMU_CAPS_FW_CFG */
               "migration-param.bandwidth", /* 
X_QEMU_CAPS_MIGRATION_PARAM_BANDWIDTH */
               "migration-param.downtime", /* 
X_QEMU_CAPS_MIGRATION_PARAM_DOWNTIME */
               "migration-param.xbzrle-cache-size", /* 
X_QEMU_CAPS_MIGRATION_PARAM_XBZRLE_CACHE_SIZE */
-              "intel-iommu.aw-bits", /* QEMU_CAPS_INTEL_IOMMU_AW_BITS */
-              "spapr-tpm-proxy", /* QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY */
 
               /* 380 */
+              "intel-iommu.aw-bits", /* QEMU_CAPS_INTEL_IOMMU_AW_BITS */
+              "spapr-tpm-proxy", /* QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY */
               "numa.hmat", /* QEMU_CAPS_NUMA_HMAT */
               "blockdev-hostdev-scsi", /* X_QEMU_CAPS_BLOCKDEV_HOSTDEV_SCSI */
               "usb-host.hostdevice", /* QEMU_CAPS_USB_HOST_HOSTDEVICE */
-              "virtio-balloon.free-page-reporting", /* 
QEMU_CAPS_VIRTIO_BALLOON_FREE_PAGE_REPORTING */
-              "block-export-add", /* X_QEMU_CAPS_BLOCK_EXPORT_ADD */
 
               /* 385 */
+              "virtio-balloon.free-page-reporting", /* 
QEMU_CAPS_VIRTIO_BALLOON_FREE_PAGE_REPORTING */
+              "block-export-add", /* X_QEMU_CAPS_BLOCK_EXPORT_ADD */
               "netdev.vhost-vdpa", /* QEMU_CAPS_NETDEV_VHOST_VDPA */
               "fsdev.createmode", /* X_QEMU_CAPS_FSDEV_CREATEMODE */
               "ncr53c90", /* QEMU_CAPS_SCSI_NCR53C90 */
-              "dc390", /* QEMU_CAPS_SCSI_DC390 */
-              "am53c974", /* QEMU_CAPS_SCSI_AM53C974 */
 
               /* 390 */
+              "dc390", /* QEMU_CAPS_SCSI_DC390 */
+              "am53c974", /* QEMU_CAPS_SCSI_AM53C974 */
               "virtio-pmem-pci", /* QEMU_CAPS_DEVICE_VIRTIO_PMEM_PCI */
               "vhost-user-fs.bootindex", /* QEMU_CAPS_VHOST_USER_FS_BOOTINDEX 
*/
               "vhost-user-blk", /* QEMU_CAPS_DEVICE_VHOST_USER_BLK */
-              "cpu-max", /* QEMU_CAPS_CPU_MAX */
-              "memory-backend-file.x-use-canonical-path-for-ramblock-id", /* 
QEMU_CAPS_X_USE_CANONICAL_PATH_FOR_RAMBLOCK_ID */
 
               /* 395 */
+              "cpu-max", /* QEMU_CAPS_CPU_MAX */
+              "memory-backend-file.x-use-canonical-path-for-ramblock-id", /* 
QEMU_CAPS_X_USE_CANONICAL_PATH_FOR_RAMBLOCK_ID */
               "vnc-opts", /* X_QEMU_CAPS_VNC_OPTS */
               "migration-param.block-bitmap-mapping", /* 
X_QEMU_CAPS_MIGRATION_PARAM_BLOCK_BITMAP_MAPPING */
               "vnc-power-control", /* QEMU_CAPS_VNC_POWER_CONTROL */
-              "audiodev", /* X_QEMU_CAPS_AUDIODEV */
-              "blockdev-backup", /* X_QEMU_CAPS_BLOCKDEV_BACKUP */
 
               /* 400 */
+              "audiodev", /* X_QEMU_CAPS_AUDIODEV */
+              "blockdev-backup", /* X_QEMU_CAPS_BLOCKDEV_BACKUP */
               "object.qapified", /* X_QEMU_CAPS_OBJECT_JSON */
               "rotation-rate", /* QEMU_CAPS_ROTATION_RATE */
               "compat-deprecated", /* X_QEMU_CAPS_COMPAT_DEPRECATED */
-              "acpi-index", /* QEMU_CAPS_ACPI_INDEX */
-              "input-linux", /* QEMU_CAPS_INPUT_LINUX */
 
               /* 405 */
+              "acpi-index", /* QEMU_CAPS_ACPI_INDEX */
+              "input-linux", /* QEMU_CAPS_INPUT_LINUX */
               "virtio-gpu-gl-pci", /* QEMU_CAPS_VIRTIO_GPU_GL_PCI */
               "virtio-vga-gl", /* QEMU_CAPS_VIRTIO_VGA_GL */
               "confidential-guest-support", /* 
QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT */
-              "query-display-options", /* X_QEMU_CAPS_QUERY_DISPLAY_OPTIONS */
-              "s390-pv-guest", /* QEMU_CAPS_S390_PV_GUEST */
 
               /* 410 */
+              "query-display-options", /* X_QEMU_CAPS_QUERY_DISPLAY_OPTIONS */
+              "s390-pv-guest", /* QEMU_CAPS_S390_PV_GUEST */
               "set-action", /* X_QEMU_CAPS_SET_ACTION */
               "virtio-blk.queue-size", /* QEMU_CAPS_VIRTIO_BLK_QUEUE_SIZE */
               "virtio-mem-pci", /* QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI */
-              "memory-backend-file.reserve", /* 
QEMU_CAPS_MEMORY_BACKEND_RESERVE */
-              "piix4.acpi-root-pci-hotplug", /* 
QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG */
 
               /* 415 */
+              "memory-backend-file.reserve", /* 
QEMU_CAPS_MEMORY_BACKEND_RESERVE */
+              "piix4.acpi-root-pci-hotplug", /* 
QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG */
               "netdev.json", /* QEMU_CAPS_NETDEV_JSON */
               "chardev.json", /* QEMU_CAPS_CHARDEV_JSON */
               "device.json", /* X_QEMU_CAPS_DEVICE_JSON_BROKEN_HOTPLUG */
-              "query-dirty-rate", /* QEMU_CAPS_QUERY_DIRTY_RATE */
-              "rbd-encryption", /* QEMU_CAPS_RBD_ENCRYPTION */
 
               /* 420 */
+              "query-dirty-rate", /* QEMU_CAPS_QUERY_DIRTY_RATE */
+              "rbd-encryption", /* QEMU_CAPS_RBD_ENCRYPTION */
               "sev-guest-kernel-hashes", /* QEMU_CAPS_SEV_GUEST_KERNEL_HASHES 
*/
               "sev-inject-launch-secret", /* 
QEMU_CAPS_SEV_INJECT_LAUNCH_SECRET */
               "device.json+hotplug", /* QEMU_CAPS_DEVICE_JSON */
-              "hvf", /* QEMU_CAPS_HVF */
-              "virtio-mem-pci.prealloc", /* 
QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI_PREALLOC */
 
               /* 425 */
+              "hvf", /* QEMU_CAPS_HVF */
+              "virtio-mem-pci.prealloc", /* 
QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI_PREALLOC */
               "calc-dirty-rate", /* QEMU_CAPS_CALC_DIRTY_RATE */
               "dirtyrate-param.mode", /* QEMU_CAPS_DIRTYRATE_MODE */
               "blockdev.nbd.tls-hostname", /* 
QEMU_CAPS_BLOCKDEV_NBD_TLS_HOSTNAME */
-              "memory-backend-file.prealloc-threads", /* 
QEMU_CAPS_MEMORY_BACKEND_PREALLOC_THREADS */
-              "virtio-iommu-pci", /* QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI */
 
               /* 430 */
+              "memory-backend-file.prealloc-threads", /* 
QEMU_CAPS_MEMORY_BACKEND_PREALLOC_THREADS */
+              "virtio-iommu-pci", /* QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI */
               "virtio-iommu.boot-bypass", /* 
QEMU_CAPS_VIRTIO_IOMMU_BOOT_BYPASS */
               "virtio-net.rss", /* QEMU_CAPS_VIRTIO_NET_RSS */
               "chardev.qemu-vdagent", /* QEMU_CAPS_CHARDEV_QEMU_VDAGENT */
-              "display-dbus", /* QEMU_CAPS_DISPLAY_DBUS */
-              "iothread.thread-pool-max", /* 
QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX */
 
               /* 435 */
+              "display-dbus", /* QEMU_CAPS_DISPLAY_DBUS */
+              "iothread.thread-pool-max", /* 
QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX */
               "usb-host.guest-resets-all", /* 
QEMU_CAPS_USB_HOST_GUESTS_RESETS_ALL */
               "migration.blocked-reasons", /* 
QEMU_CAPS_MIGRATION_BLOCKED_REASONS */
               "query-stats", /* QEMU_CAPS_QUERY_STATS */
-              "query-stats-schemas", /* QEMU_CAPS_QUERY_STATS_SCHEMAS */
-              "sgx-epc", /* QEMU_CAPS_SGX_EPC */
 
               /* 440 */
+              "query-stats-schemas", /* QEMU_CAPS_QUERY_STATS_SCHEMAS */
+              "sgx-epc", /* QEMU_CAPS_SGX_EPC */
               "thread-context", /* QEMU_CAPS_THREAD_CONTEXT */
               "screenshot-format-png", /* QEMU_CAPS_SCREENSHOT_FORMAT_PNG */
               "machine-hpet", /* QEMU_CAPS_MACHINE_HPET */
-              "netdev.stream", /* QEMU_CAPS_NETDEV_STREAM */
-              "virtio-crypto", /* QEMU_CAPS_DEVICE_VIRTIO_CRYPTO */
 
               /* 445 */
+              "netdev.stream", /* QEMU_CAPS_NETDEV_STREAM */
+              "virtio-crypto", /* QEMU_CAPS_DEVICE_VIRTIO_CRYPTO */
               "cryptodev-backend-lkcf", /* QEMU_CAPS_OBJECT_CRYPTO_LKCF */
               "pvpanic-pci", /* QEMU_CAPS_DEVICE_PANIC_PCI */
               "netdev.stream.reconnect", /* QEMU_CAPS_NETDEV_STREAM_RECONNECT 
*/
-              "virtio-gpu.blob", /* QEMU_CAPS_VIRTIO_GPU_BLOB */
-              "rbd-encryption-layering", /* QEMU_CAPS_RBD_ENCRYPTION_LAYERING 
*/
 
               /* 450 */
+              "virtio-gpu.blob", /* QEMU_CAPS_VIRTIO_GPU_BLOB */
+              "rbd-encryption-layering", /* QEMU_CAPS_RBD_ENCRYPTION_LAYERING 
*/
               "rbd-encryption-luks-any", /* QEMU_CAPS_RBD_ENCRYPTION_LUKS_ANY 
*/
               "qcow2-discard-no-unref", /* QEMU_CAPS_QCOW2_DISCARD_NO_UNREF */
               "run-with.async-teardown", /* QEMU_CAPS_RUN_WITH_ASYNC_TEARDOWN 
*/
-              "virtio-blk-vhost-vdpa", /* 
QEMU_CAPS_DEVICE_VIRTIO_BLK_VHOST_VDPA */
-              "virtio-blk.iothread-mapping", /* 
QEMU_CAPS_VIRTIO_BLK_IOTHREAD_MAPPING */
 
               /* 455 */
+              "virtio-blk-vhost-vdpa", /* 
QEMU_CAPS_DEVICE_VIRTIO_BLK_VHOST_VDPA */
+              "virtio-blk.iothread-mapping", /* 
QEMU_CAPS_VIRTIO_BLK_IOTHREAD_MAPPING */
               "smp-clusters", /* QEMU_CAPS_SMP_CLUSTERS */
               "virtio-mem-pci.dynamic-memslots", /* 
QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI_DYNAMIC_MEMSLOTS */
               "blockjob.backing-mask-protocol", /* 
QEMU_CAPS_BLOCKJOB_BACKING_MASK_PROTOCOL */
-              "display-reload", /* QEMU_CAPS_DISPLAY_RELOAD */
-              "usb-mtp", /* QEMU_CAPS_DEVICE_USB_MTP */
 
               /* 460 */
+              "display-reload", /* QEMU_CAPS_DISPLAY_RELOAD */
+              "usb-mtp", /* QEMU_CAPS_DEVICE_USB_MTP */
               "machine.virt.ras", /* QEMU_CAPS_MACHINE_VIRT_RAS */
               "virtio-sound", /* QEMU_CAPS_DEVICE_VIRTIO_SOUND */
               "sev-snp-guest", /* QEMU_CAPS_SEV_SNP_GUEST */
-              "netdev.user", /* QEMU_CAPS_NETDEV_USER */
-              "acpi-erst", /* QEMU_CAPS_DEVICE_ACPI_ERST */
 
               /* 465 */
+              "netdev.user", /* QEMU_CAPS_NETDEV_USER */
+              "acpi-erst", /* QEMU_CAPS_DEVICE_ACPI_ERST */
               "intel-iommu.dma-translation", /* 
QEMU_CAPS_INTEL_IOMMU_DMA_TRANSLATION */
               "machine-i8042-opt", /* QEMU_CAPS_MACHINE_I8042_OPT */
               "snapshot-internal-qmp", /* X_QEMU_CAPS_SNAPSHOT_INTERNAL_QMP */
-              "chardev-reconnect-miliseconds", /* 
QEMU_CAPS_CHARDEV_RECONNECT_MILISECONDS */
-              "virtio-ccw.loadparm", /* QEMU_CAPS_VIRTIO_CCW_DEVICE_LOADPARM */
 
               /* 470 */
+              "chardev-reconnect-miliseconds", /* 
QEMU_CAPS_CHARDEV_RECONNECT_MILISECONDS */
+              "virtio-ccw.loadparm", /* QEMU_CAPS_VIRTIO_CCW_DEVICE_LOADPARM */
               "netdev-stream-reconnect-miliseconds", /* 
QEMU_CAPS_NETDEV_STREAM_RECONNECT_MILISECONDS */
               "query-cpu-model-expansion.deprecated-props", /* 
QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_DEPRECATED_PROPS */
               "migrate-incoming.exit-on-error", /* 
QEMU_CAPS_MIGRATE_INCOMING_EXIT_ON_ERROR */
-              "machine.virt.aia", /* QEMU_CAPS_MACHINE_VIRT_AIA */
-              "virtio-mem-ccw", /* QEMU_CAPS_DEVICE_VIRTIO_MEM_CCW */
 
               /* 475 */
+              "machine.virt.aia", /* QEMU_CAPS_MACHINE_VIRT_AIA */
+              "virtio-mem-ccw", /* QEMU_CAPS_DEVICE_VIRTIO_MEM_CCW */
               "blockdev-set-active", /* QEMU_CAPS_BLOCKDEV_SET_ACTIVE */
               "shim", /* QEMU_CAPS_MACHINE_SHIM */
               "virtio-scsi.iothread-mapping", /* 
QEMU_CAPS_VIRTIO_SCSI_IOTHREAD_MAPPING */
-              "machine.virt.highmem-mmio-size", /* 
QEMU_CAPS_MACHINE_VIRT_HIGHMEM_MMIO_SIZE */
-              "bus-floppy", /* QEMU_CAPS_BUS_FLOPPY */
 
               /* 480 */
+              "machine.virt.highmem-mmio-size", /* 
QEMU_CAPS_MACHINE_VIRT_HIGHMEM_MMIO_SIZE */
+              "bus-floppy", /* QEMU_CAPS_BUS_FLOPPY */
               "nvme", /* QEMU_CAPS_DEVICE_NVME */
               "nvme-ns", /* QEMU_CAPS_DEVICE_NVME_NS */
               "amd-iommu", /* QEMU_CAPS_AMD_IOMMU */
-              "amd-iommu.pci-id", /* QEMU_CAPS_AMD_IOMMU_PCI_ID */
-              "usb-bot", /* QEMU_CAPS_DEVICE_USB_BOT */
 
               /* 485 */
+              "amd-iommu.pci-id", /* QEMU_CAPS_AMD_IOMMU_PCI_ID */
+              "usb-bot", /* QEMU_CAPS_DEVICE_USB_BOT */
               "tdx-guest", /* QEMU_CAPS_TDX_GUEST */
               "qom-list-get", /* QEMU_CAPS_QOM_LIST_GET */
               "acpi-generic-initiator", /* QEMU_CAPS_ACPI_GENERIC_INITIATOR */
-              "disk-timed-stats", /* QEMU_CAPS_DISK_TIMED_STATS */
-              "query-accelerators", /* QEMU_CAPS_QUERY_ACCELERATORS */
 
               /* 490 */
+              "disk-timed-stats", /* QEMU_CAPS_DISK_TIMED_STATS */
+              "query-accelerators", /* QEMU_CAPS_QUERY_ACCELERATORS */
               "mshv", /* QEMU_CAPS_MSHV */
               "virtio-iommu.aw-bits", /* QEMU_CAPS_VIRTIO_IOMMU_AW_BITS */
               "scsi-block.migrate-pr", /* 
QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR */
-              "iommufd", /* QEMU_CAPS_OBJECT_IOMMUFD */
-              "uefi-vars", /* QEMU_CAPS_DEVICE_UEFI_VARS */
 
               /* 495 */
+              "iommufd", /* QEMU_CAPS_OBJECT_IOMMUFD */
+              "uefi-vars", /* QEMU_CAPS_DEVICE_UEFI_VARS */
               "query-block-flat", /* QEMU_CAPS_QUERY_BLOCK_FLAT */
               "amd-iommu.xtsup", /* QEMU_CAPS_AMD_IOMMU_XTSUP */
               "blockdev-mirror.target-is-zero", /* 
QEMU_CAPS_BLOCKDEV_MIRROR_TARGET_IS_ZERO */
-              "object-monitor-qmp", /* QEMU_CAPS_OBJECT_MONITOR_QMP */
-              "arm-smmuv3", /* QEMU_CAPS_DEVICE_ARM_SMMUV3 */
 
               /* 500 */
+              "object-monitor-qmp", /* QEMU_CAPS_OBJECT_MONITOR_QMP */
+              "arm-smmuv3", /* QEMU_CAPS_DEVICE_ARM_SMMUV3 */
               "arm-smmuv3.smmu_per_bus", /* QEMU_CAPS_ARM_SMMUV3_SMMU_PER_BUS 
*/
               "arm-smmuv3.accel", /* QEMU_CAPS_ARM_SMMUV3_ACCEL */
               "arm-smmuv3.cmdqv", /* QEMU_CAPS_ARM_SMMUV3_CMDQV */
+
+              /* 505 */
               "iothread.poll-weight", /* QEMU_CAPS_IOTHREAD_POLL_WEIGHT */
               "win-dmp.guest-aware", /* QEMU_CAPS_WIN_DMP_GUEST_AWARE */
     );
@@ -1542,6 +1546,8 @@ static struct virQEMUCapsDevicePropsFlags 
virQEMUCapsDevicePropsVirtioNet[] = {
 
 static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsPCIeRootPort[] 
= {
     { "hotplug", QEMU_CAPS_PCIE_ROOT_PORT_HOTPLUG, NULL },
+    { "speed", QEMU_CAPS_PCIE_ROOT_PORT_SPEED, NULL },
+    { "width", QEMU_CAPS_PCIE_ROOT_PORT_WIDTH, NULL },
 };
 
 static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsUSBHost[] = {
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 3e76a0f1cc..70071355c8 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -558,198 +558,202 @@ typedef enum { /* virQEMUCapsFlags grouping marker for 
syntax-check */
     QEMU_CAPS_PCIE_ROOT_PORT_HOTPLUG, /* pcie-root-port.hotplug */
 
     /* 365 */
+    QEMU_CAPS_PCIE_ROOT_PORT_SPEED, /* pcie-root-port.speed */
+    QEMU_CAPS_PCIE_ROOT_PORT_WIDTH, /* pcie-root-port.width */
     QEMU_CAPS_AIO_IO_URING, /* -blockdev {...,"aio":"io_uring",...} */
     X_QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC, /* -machine pseries.cap-cfpc */
     X_QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC, /* -machine pseries.cap-sbbc */
-    X_QEMU_CAPS_MACHINE_PSERIES_CAP_IBS, /* -machine pseries.cap-ibs */
-    QEMU_CAPS_TCG, /* QEMU does support TCG */
 
     /* 370 */
+    X_QEMU_CAPS_MACHINE_PSERIES_CAP_IBS, /* -machine pseries.cap-ibs */
+    QEMU_CAPS_TCG, /* QEMU does support TCG */
     QEMU_CAPS_VIRTIO_BLK_SCSI_DEFAULT_DISABLED, /* virtio-blk-pci.scsi 
disabled by default */
     QEMU_CAPS_SCSI_PVSCSI, /* -device pvscsi */
     QEMU_CAPS_CPU_MIGRATABLE, /* -cpu ...,migratable=on|off */
-    X_QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_MIGRATABLE, /* 
query-cpu-model-expansion supports migratable:false */
-    X_QEMU_CAPS_FW_CFG, /* -fw_cfg command line option */
 
     /* 375 */
+    X_QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_MIGRATABLE, /* 
query-cpu-model-expansion supports migratable:false */
+    X_QEMU_CAPS_FW_CFG, /* -fw_cfg command line option */
     X_QEMU_CAPS_MIGRATION_PARAM_BANDWIDTH, /* max-bandwidth field in 
migrate-set-parameters */
     X_QEMU_CAPS_MIGRATION_PARAM_DOWNTIME, /* downtime-limit field in 
migrate-set-parameters */
     X_QEMU_CAPS_MIGRATION_PARAM_XBZRLE_CACHE_SIZE, /* xbzrle-cache-size field 
in migrate-set-parameters */
-    QEMU_CAPS_INTEL_IOMMU_AW_BITS, /* intel-iommu.aw-bits */
-    QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY, /* -device spapr-tpm-proxy */
 
     /* 380 */
+    QEMU_CAPS_INTEL_IOMMU_AW_BITS, /* intel-iommu.aw-bits */
+    QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY, /* -device spapr-tpm-proxy */
     QEMU_CAPS_NUMA_HMAT, /* -numa hmat */
     X_QEMU_CAPS_BLOCKDEV_HOSTDEV_SCSI, /* -blockdev used for (i)SCSI hostdevs 
*/
     QEMU_CAPS_USB_HOST_HOSTDEVICE, /* -device usb-host.hostdevice */
-    QEMU_CAPS_VIRTIO_BALLOON_FREE_PAGE_REPORTING, /*virtio balloon 
free-page-reporting */
-    X_QEMU_CAPS_BLOCK_EXPORT_ADD, /* 'block-export-add' command is supported */
 
     /* 385 */
+    QEMU_CAPS_VIRTIO_BALLOON_FREE_PAGE_REPORTING, /*virtio balloon 
free-page-reporting */
+    X_QEMU_CAPS_BLOCK_EXPORT_ADD, /* 'block-export-add' command is supported */
     QEMU_CAPS_NETDEV_VHOST_VDPA, /* -netdev vhost-vdpa*/
     X_QEMU_CAPS_FSDEV_CREATEMODE, /* fsdev.createmode */
     QEMU_CAPS_SCSI_NCR53C90, /* built-in SCSI */
-    QEMU_CAPS_SCSI_DC390, /* -device dc-390 */
-    QEMU_CAPS_SCSI_AM53C974, /* -device am53c974 */
 
     /* 390 */
+    QEMU_CAPS_SCSI_DC390, /* -device dc-390 */
+    QEMU_CAPS_SCSI_AM53C974, /* -device am53c974 */
     QEMU_CAPS_DEVICE_VIRTIO_PMEM_PCI, /* -device virtio-pmem-pci */
     QEMU_CAPS_VHOST_USER_FS_BOOTINDEX, /* vhost-user-fs.bootindex */
     QEMU_CAPS_DEVICE_VHOST_USER_BLK, /* -device vhost-user-blk */
-    QEMU_CAPS_CPU_MAX, /* -cpu max */
-    QEMU_CAPS_X_USE_CANONICAL_PATH_FOR_RAMBLOCK_ID, /* -object 
memory-backend-file,x-use-canonical-path-for-ramblock-id= */
 
     /* 395 */
+    QEMU_CAPS_CPU_MAX, /* -cpu max */
+    QEMU_CAPS_X_USE_CANONICAL_PATH_FOR_RAMBLOCK_ID, /* -object 
memory-backend-file,x-use-canonical-path-for-ramblock-id= */
     X_QEMU_CAPS_VNC_OPTS, /* -vnc uses QemuOpts parser instead of custom code 
*/
     X_QEMU_CAPS_MIGRATION_PARAM_BLOCK_BITMAP_MAPPING, /* block-bitmap-mapping 
in migrate-set-parameters */
     QEMU_CAPS_VNC_POWER_CONTROL, /* -vnc power-control option */
-    X_QEMU_CAPS_AUDIODEV, /* -audiodev instead of QEMU_AUDIO_DRV */
-    X_QEMU_CAPS_BLOCKDEV_BACKUP, /* qemu supports the blockdev-backup job */
 
     /* 400 */
+    X_QEMU_CAPS_AUDIODEV, /* -audiodev instead of QEMU_AUDIO_DRV */
+    X_QEMU_CAPS_BLOCKDEV_BACKUP, /* qemu supports the blockdev-backup job */
     X_QEMU_CAPS_OBJECT_JSON, /* parameters for object-add are formally 
described */
     QEMU_CAPS_ROTATION_RATE, /* scsi-disk / ide-drive rotation-rate prop */
     X_QEMU_CAPS_COMPAT_DEPRECATED, /* -compat deprecated-(input|output) is 
supported */
-    QEMU_CAPS_ACPI_INDEX, /* PCI device 'acpi-index' property */
-    QEMU_CAPS_INPUT_LINUX, /* -object input-linux */
 
     /* 405 */
+    QEMU_CAPS_ACPI_INDEX, /* PCI device 'acpi-index' property */
+    QEMU_CAPS_INPUT_LINUX, /* -object input-linux */
     QEMU_CAPS_VIRTIO_GPU_GL_PCI, /* -device virtio-gpu-gl-pci */
     QEMU_CAPS_VIRTIO_VGA_GL, /* -device virtio-vga-gl */
     QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT, /* -machine 
confidential-guest-support */
-    X_QEMU_CAPS_QUERY_DISPLAY_OPTIONS, /* 'query-display-options' qmp command 
present */
-    QEMU_CAPS_S390_PV_GUEST, /* -object s390-pv-guest,... */
 
     /* 410 */
+    X_QEMU_CAPS_QUERY_DISPLAY_OPTIONS, /* 'query-display-options' qmp command 
present */
+    QEMU_CAPS_S390_PV_GUEST, /* -object s390-pv-guest,... */
     X_QEMU_CAPS_SET_ACTION, /* 'set-action' QMP command */
     QEMU_CAPS_VIRTIO_BLK_QUEUE_SIZE, /* virtio-blk-*.queue-size */
     QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI, /* -device virtio-mem-pci */
-    QEMU_CAPS_MEMORY_BACKEND_RESERVE, /* -object memory-backend-*.reserve= */
-    QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG, /* -M pc 
PIIX4_PM.acpi-root-pci-hotplug */
 
     /* 415 */
+    QEMU_CAPS_MEMORY_BACKEND_RESERVE, /* -object memory-backend-*.reserve= */
+    QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG, /* -M pc 
PIIX4_PM.acpi-root-pci-hotplug */
     QEMU_CAPS_NETDEV_JSON, /* -netdev accepts JSON */
     QEMU_CAPS_CHARDEV_JSON, /* Reserved for '-chardev' JSON support. For now 
used only in tests. */
     X_QEMU_CAPS_DEVICE_JSON_BROKEN_HOTPLUG, /* -device accepts JSON (must not 
be used - users are filtering the capbility) */
-    QEMU_CAPS_QUERY_DIRTY_RATE, /* accepts query-dirty-rate */
-    QEMU_CAPS_RBD_ENCRYPTION, /* Ceph RBD encryption support */
 
     /* 420 */
+    QEMU_CAPS_QUERY_DIRTY_RATE, /* accepts query-dirty-rate */
+    QEMU_CAPS_RBD_ENCRYPTION, /* Ceph RBD encryption support */
     QEMU_CAPS_SEV_GUEST_KERNEL_HASHES, /* sev-guest.kernel-hashes= */
     QEMU_CAPS_SEV_INJECT_LAUNCH_SECRET, /* 'sev-inject-launch-secret' qmp 
command present */
     QEMU_CAPS_DEVICE_JSON, /* -device accepts JSON (and works with hot-unplug) 
*/
-    QEMU_CAPS_HVF, /* Whether Hypervisor.framework is available */
-    QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI_PREALLOC, /* -device 
virtio-mem-pci.prealloc= */
 
     /* 425 */
+    QEMU_CAPS_HVF, /* Whether Hypervisor.framework is available */
+    QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI_PREALLOC, /* -device 
virtio-mem-pci.prealloc= */
     QEMU_CAPS_CALC_DIRTY_RATE, /* accepts calc-dirty-rate */
     QEMU_CAPS_DIRTYRATE_MODE , /* calc-dirty-rate accepts mode parameter */
     QEMU_CAPS_BLOCKDEV_NBD_TLS_HOSTNAME, /* tls hostname can be overridden for 
NBD clients */
-    QEMU_CAPS_MEMORY_BACKEND_PREALLOC_THREADS, /* -object 
memory-backend-*.prealloc-threads */
-    QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI, /* -device virtio-iommu-pci */
 
     /* 430 */
+    QEMU_CAPS_MEMORY_BACKEND_PREALLOC_THREADS, /* -object 
memory-backend-*.prealloc-threads */
+    QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI, /* -device virtio-iommu-pci */
     QEMU_CAPS_VIRTIO_IOMMU_BOOT_BYPASS, /* virtio-iommu.boot-bypass */
     QEMU_CAPS_VIRTIO_NET_RSS, /* virtio-net rss feature */
     QEMU_CAPS_CHARDEV_QEMU_VDAGENT, /* -chardev qemu-vdagent */
-    QEMU_CAPS_DISPLAY_DBUS, /* -display dbus */
-    QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX, /* -object iothread.thread-pool-max */
 
     /* 435 */
+    QEMU_CAPS_DISPLAY_DBUS, /* -display dbus */
+    QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX, /* -object iothread.thread-pool-max */
     QEMU_CAPS_USB_HOST_GUESTS_RESETS_ALL, /* -device usb-host.guest-resets-all 
*/
     QEMU_CAPS_MIGRATION_BLOCKED_REASONS, /* query-migrate returns 
'blocked-reasons */
     QEMU_CAPS_QUERY_STATS,  /* accepts query-stats */
-    QEMU_CAPS_QUERY_STATS_SCHEMAS,  /* accepts query-stats-schemas */
-    QEMU_CAPS_SGX_EPC, /* -object sgx-epc,... */
 
     /* 440 */
+    QEMU_CAPS_QUERY_STATS_SCHEMAS,  /* accepts query-stats-schemas */
+    QEMU_CAPS_SGX_EPC, /* -object sgx-epc,... */
     QEMU_CAPS_THREAD_CONTEXT, /* -object thread-context */
     QEMU_CAPS_SCREENSHOT_FORMAT_PNG, /* screendump command supports png format 
*/
     QEMU_CAPS_MACHINE_HPET, /* the HPET timer is configured via -machine, 
rather than -no-hpet */
-    QEMU_CAPS_NETDEV_STREAM, /* -netdev stream */
-    QEMU_CAPS_DEVICE_VIRTIO_CRYPTO, /* virtio-crypto device */
 
     /* 445 */
+    QEMU_CAPS_NETDEV_STREAM, /* -netdev stream */
+    QEMU_CAPS_DEVICE_VIRTIO_CRYPTO, /* virtio-crypto device */
     QEMU_CAPS_OBJECT_CRYPTO_LKCF, /* -object cryptodev-backend-lkcf */
     QEMU_CAPS_DEVICE_PANIC_PCI, /* -device pvpanic-pci */
     QEMU_CAPS_NETDEV_STREAM_RECONNECT, /* -netdev stream supports reconnect */
-    QEMU_CAPS_VIRTIO_GPU_BLOB, /* -device virtio-gpu-*.blob= */
-    QEMU_CAPS_RBD_ENCRYPTION_LAYERING, /* layered encryption support for Ceph 
RBD */
 
     /* 450 */
+    QEMU_CAPS_VIRTIO_GPU_BLOB, /* -device virtio-gpu-*.blob= */
+    QEMU_CAPS_RBD_ENCRYPTION_LAYERING, /* layered encryption support for Ceph 
RBD */
     QEMU_CAPS_RBD_ENCRYPTION_LUKS_ANY, /* luks-any (LUKS and LUKS2) encryption 
format for Ceph RBD */
     QEMU_CAPS_QCOW2_DISCARD_NO_UNREF, /* qcow2 block driver allows discards 
without unrefing the sector */
     QEMU_CAPS_RUN_WITH_ASYNC_TEARDOWN, /* asynchronous teardown -run-with 
async-teardown=on|off */
-    QEMU_CAPS_DEVICE_VIRTIO_BLK_VHOST_VDPA, /* virtio-blk-vhost-vdpa block 
driver */
-    QEMU_CAPS_VIRTIO_BLK_IOTHREAD_MAPPING, /* virtio-blk supports 
per-virtqueue iothread mapping */
 
     /* 455 */
+    QEMU_CAPS_DEVICE_VIRTIO_BLK_VHOST_VDPA, /* virtio-blk-vhost-vdpa block 
driver */
+    QEMU_CAPS_VIRTIO_BLK_IOTHREAD_MAPPING, /* virtio-blk supports 
per-virtqueue iothread mapping */
     QEMU_CAPS_SMP_CLUSTERS, /* -smp clusters= */
     QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI_DYNAMIC_MEMSLOTS, /* -device 
virtio-mem-pci.dynamic-memslots= */
     QEMU_CAPS_BLOCKJOB_BACKING_MASK_PROTOCOL, /* backing-mask-protocol of 
block-commit/block-stream */
-    QEMU_CAPS_DISPLAY_RELOAD, /* 'display-reload' qmp command is supported */
-    QEMU_CAPS_DEVICE_USB_MTP, /* -device usb-mtp */
 
     /* 460 */
+    QEMU_CAPS_DISPLAY_RELOAD, /* 'display-reload' qmp command is supported */
+    QEMU_CAPS_DEVICE_USB_MTP, /* -device usb-mtp */
     QEMU_CAPS_MACHINE_VIRT_RAS, /* -machine virt,ras= */
     QEMU_CAPS_DEVICE_VIRTIO_SOUND, /* -device virtio-sound-* */
     QEMU_CAPS_SEV_SNP_GUEST, /* -object sev-snp-guest */
-    QEMU_CAPS_NETDEV_USER, /* -netdev user */
-    QEMU_CAPS_DEVICE_ACPI_ERST, /* -device acpi-erst */
 
     /* 465 */
+    QEMU_CAPS_NETDEV_USER, /* -netdev user */
+    QEMU_CAPS_DEVICE_ACPI_ERST, /* -device acpi-erst */
     QEMU_CAPS_INTEL_IOMMU_DMA_TRANSLATION, /* intel-iommu.dma-translation */
     QEMU_CAPS_MACHINE_I8042_OPT, /* -machine xxx,i8042=on/off; use 
virQEMUCapsSupportsI8042Toggle() to query this capability */
     X_QEMU_CAPS_SNAPSHOT_INTERNAL_QMP, /* internal snapshot support via QMP 
commands 'snapshot-save'/'snapshot-delete' */
-    QEMU_CAPS_CHARDEV_RECONNECT_MILISECONDS, /* 'reconnect-ms' option for 
chardevs supported */
-    QEMU_CAPS_VIRTIO_CCW_DEVICE_LOADPARM, /* loadparm available on CCW device 
for multi device boot */
 
     /* 470 */
+    QEMU_CAPS_CHARDEV_RECONNECT_MILISECONDS, /* 'reconnect-ms' option for 
chardevs supported */
+    QEMU_CAPS_VIRTIO_CCW_DEVICE_LOADPARM, /* loadparm available on CCW device 
for multi device boot */
     QEMU_CAPS_NETDEV_STREAM_RECONNECT_MILISECONDS, /* 'reconnect-ms' option 
for netdev stream supported */
     QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_DEPRECATED_PROPS, /* 
query-cpu-model-expansion may report deprecated CPU properties */
     QEMU_CAPS_MIGRATE_INCOMING_EXIT_ON_ERROR, /* exit-on-error argument of 
migrate-incoming command */
-    QEMU_CAPS_MACHINE_VIRT_AIA, /* -machine virt,aia=(none|aplic|aplic-imsic), 
RISC-V only */
-    QEMU_CAPS_DEVICE_VIRTIO_MEM_CCW, /* -device virtio-mem-ccw */
 
     /* 475 */
+    QEMU_CAPS_MACHINE_VIRT_AIA, /* -machine virt,aia=(none|aplic|aplic-imsic), 
RISC-V only */
+    QEMU_CAPS_DEVICE_VIRTIO_MEM_CCW, /* -device virtio-mem-ccw */
     QEMU_CAPS_BLOCKDEV_SET_ACTIVE, /* blockdev-set-active QMP command 
supported */
     QEMU_CAPS_MACHINE_SHIM, /* -shim command line argument */
     QEMU_CAPS_VIRTIO_SCSI_IOTHREAD_MAPPING, /* virtio-scsi supports 
per-virtqueue iothread mapping */
-    QEMU_CAPS_MACHINE_VIRT_HIGHMEM_MMIO_SIZE, /* -machine 
virt,highmem-mmio-size=<size> */
-    QEMU_CAPS_BUS_FLOPPY, /* floppy bus supported (isa-fdc/sysbus-fdc) */
 
     /* 480 */
+    QEMU_CAPS_MACHINE_VIRT_HIGHMEM_MMIO_SIZE, /* -machine 
virt,highmem-mmio-size=<size> */
+    QEMU_CAPS_BUS_FLOPPY, /* floppy bus supported (isa-fdc/sysbus-fdc) */
     QEMU_CAPS_DEVICE_NVME, /* -device nvme */
     QEMU_CAPS_DEVICE_NVME_NS, /* -device nvme-ns */
     QEMU_CAPS_AMD_IOMMU, /* -device amd-iommu */
-    QEMU_CAPS_AMD_IOMMU_PCI_ID, /* amd-iommu.pci-id */
-    QEMU_CAPS_DEVICE_USB_BOT, /* -device usb-bot */
 
     /* 485 */
+    QEMU_CAPS_AMD_IOMMU_PCI_ID, /* amd-iommu.pci-id */
+    QEMU_CAPS_DEVICE_USB_BOT, /* -device usb-bot */
     QEMU_CAPS_TDX_GUEST, /* -object tdx-guest,... */
     QEMU_CAPS_QOM_LIST_GET, /* qom-list-get QMP command */
     QEMU_CAPS_ACPI_GENERIC_INITIATOR, /* -object acpi-generic-initiator */
-    QEMU_CAPS_DISK_TIMED_STATS, /* timed stats support ('stats-intervals' 
property of disk frontends) */
-    QEMU_CAPS_QUERY_ACCELERATORS, /* query-accelerators command */
 
     /* 490 */
+    QEMU_CAPS_DISK_TIMED_STATS, /* timed stats support ('stats-intervals' 
property of disk frontends) */
+    QEMU_CAPS_QUERY_ACCELERATORS, /* query-accelerators command */
     QEMU_CAPS_MSHV, /* -accel mshv */
     QEMU_CAPS_VIRTIO_IOMMU_AW_BITS, /* virtio-iommu.aw-bits */
     QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR, /* persistent reservation 
migration support */
-    QEMU_CAPS_OBJECT_IOMMUFD, /* -object iommufd */
-    QEMU_CAPS_DEVICE_UEFI_VARS, /* -device uefi-vars-{x64,sysbus} */
 
     /* 495 */
+    QEMU_CAPS_OBJECT_IOMMUFD, /* -object iommufd */
+    QEMU_CAPS_DEVICE_UEFI_VARS, /* -device uefi-vars-{x64,sysbus} */
     QEMU_CAPS_QUERY_BLOCK_FLAT, /* 'query-block' command supports 'flat' */
     QEMU_CAPS_AMD_IOMMU_XTSUP, /* amd-iommu.xtsup */
     QEMU_CAPS_BLOCKDEV_MIRROR_TARGET_IS_ZERO, /* 'blockdev-mirror' supports 
'target-is-zero' */
-    QEMU_CAPS_OBJECT_MONITOR_QMP, /* 'monitor-qmp' -object */
-    QEMU_CAPS_DEVICE_ARM_SMMUV3, /* -device arm-smmuv3 */
 
     /* 500 */
+    QEMU_CAPS_OBJECT_MONITOR_QMP, /* 'monitor-qmp' -object */
+    QEMU_CAPS_DEVICE_ARM_SMMUV3, /* -device arm-smmuv3 */
     QEMU_CAPS_ARM_SMMUV3_SMMU_PER_BUS, /* arm-smmuv3.smmu_per_bus */
     QEMU_CAPS_ARM_SMMUV3_ACCEL, /* arm-smmuv3.accel */
     QEMU_CAPS_ARM_SMMUV3_CMDQV, /* arm-smmuv3.cmdqv */
+
+    /* 505 */
     QEMU_CAPS_IOTHREAD_POLL_WEIGHT, /* -object iothread.poll-weight */
     QEMU_CAPS_WIN_DMP_GUEST_AWARE, /* 'win-dmp' is offered only to a guest 
that can use it */
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index bcddb9c922..e3e4fe2538 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -182,6 +182,26 @@ qemuOnOffAuto(virTristateSwitch s)
 }
 
 
+/* Map domain GT/s values to QEMU PCIELinkSpeed enum strings. */
+static const char *
+qemuPCIELinkSpeedString(double speed)
+{
+    if (speed == 2.5)
+        return "2_5";
+    if (speed == 5.0)
+        return "5";
+    if (speed == 8.0)
+        return "8";
+    if (speed == 16.0)
+        return "16";
+    if (speed == 32.0)
+        return "32";
+    if (speed == 64.0)
+        return "64";
+    return NULL;
+}
+
+
 static int
 qemuBuildObjectCommandlineFromJSON(virCommand *cmd,
                                    virJSONValue *props)
@@ -2790,6 +2810,32 @@ qemuBuildControllerPCIDevProps(virDomainControllerDef 
*def,
         return -1;
     }
 
+    /* Options common to all PCIe ports. */
+    if (def->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT ||
+        def->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT ||
+        def->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT) 
{
+        if (pciopts->speed > 0) {
+            const char *speedstr = qemuPCIELinkSpeedString(pciopts->speed);
+
+            if (!speedstr) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("Unexpected PCI controller link speed %1$g"),
+                               pciopts->speed);
+                return -1;
+            }
+
+            if (virJSONValueObjectAdd(&props, "S:speed", speedstr, NULL) < 0)
+                return -1;
+        }
+
+        if (pciopts->width > 0) {
+            g_autofree char *widthstr = g_strdup_printf("%d", pciopts->width);
+
+            if (virJSONValueObjectAdd(&props, "s:width", widthstr, NULL) < 0)
+                return -1;
+        }
+    }
+
     *devprops = g_steal_pointer(&props);
     return 0;
 }
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 16beb3ca6a..562d6117af 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -4762,6 +4762,87 @@ qemuValidateDomainDeviceDefControllerPCI(const 
virDomainControllerDef *cont,
         return -1;
     }
 
+    /* speed and width */
+    switch ((virDomainControllerModelPCI) cont->model) {
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT:
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT:
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT:
+        if (pciopts->speed != -1 &&
+            (pciopts->speed != 2.5 &&
+             pciopts->speed != 5.0 &&
+             pciopts->speed != 8.0 &&
+             pciopts->speed != 16.0 &&
+             pciopts->speed != 32.0 &&
+             pciopts->speed != 64.0)) {
+            virReportControllerInvalidValue(cont, model, modelName, "speed");
+            return -1;
+        }
+        if (pciopts->speed != -1) {
+            if (pciopts->modelName == 
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_X3130_UPSTREAM ||
+                pciopts->modelName == 
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_XIO3130_DOWNSTREAM) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("setting the '%1$s' property on a '%2$s' 
device is not supported"),
+                               "speed", modelName);
+                return -1;
+            }
+            if (pciopts->modelName == 
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_ROOT_PORT &&
+                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCIE_ROOT_PORT_SPEED)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("setting the '%1$s' property on a '%2$s' 
device is not supported by this QEMU binary"),
+                               "speed", modelName);
+                return -1;
+            }
+        }
+
+        if (pciopts->width != -1 &&
+            pciopts->width != 1 &&
+            pciopts->width != 2 &&
+            pciopts->width != 4 &&
+            pciopts->width != 8 &&
+            pciopts->width != 16 &&
+            pciopts->width != 32) {
+            virReportControllerInvalidValue(cont, model, modelName, "width");
+            return -1;
+        }
+        if (pciopts->width != -1) {
+            if (pciopts->modelName == 
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_X3130_UPSTREAM ||
+                pciopts->modelName == 
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_XIO3130_DOWNSTREAM) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("setting the '%1$s' property on a '%2$s' 
device is not supported"),
+                               "width", modelName);
+                return -1;
+            }
+            if (pciopts->modelName == 
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_ROOT_PORT &&
+                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCIE_ROOT_PORT_WIDTH)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("setting the '%1$s' property on a '%2$s' 
device is not supported by this QEMU binary"),
+                               "width", modelName);
+                return -1;
+            }
+        }
+        break;
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
+    case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS:
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS:
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE:
+        if (pciopts->speed != -1) {
+            virReportControllerInvalidOption(cont, model, modelName, "speed");
+            return -1;
+        }
+        if (pciopts->width != -1) {
+            virReportControllerInvalidOption(cont, model, modelName, "width");
+            return -1;
+        }
+        break;
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT:
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
+    default:
+        virReportEnumRangeError(virDomainControllerModelPCI, cont->model);
+    }
+
     /* hotplug */
     if (pciopts->hotplug != VIR_TRISTATE_SWITCH_ABSENT) {
         switch ((virDomainControllerModelPCI) cont->model) {
diff --git a/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.replies 
b/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.replies
index bead7636b1..84ddf0e6dd 100644
--- a/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.replies
+++ b/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.replies
@@ -32371,7 +32371,7 @@
     },
     {
       "default-value": "32",
-      "name": "x-width",
+      "name": "width",
       "description": "1/2/4/8/12/16/32",
       "type": "PCIELinkWidth"
     },
@@ -32387,7 +32387,7 @@
     },
     {
       "default-value": "16",
-      "name": "x-speed",
+      "name": "speed",
       "description": "2_5/5/8/16/32/64",
       "type": "PCIELinkSpeed"
     },
diff --git a/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml 
b/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml
index 05e6749a17..601cb394b5 100644
--- a/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml
@@ -124,6 +124,8 @@
   <flag name='vhost-user-fs'/>
   <flag name='fsdev.multidevs'/>
   <flag name='pcie-root-port.hotplug'/>
+  <flag name='pcie-root-port.speed'/>
+  <flag name='pcie-root-port.width'/>
   <flag name='aio.io_uring'/>
   <flag name='tcg'/>
   <flag name='pvscsi'/>
diff --git 
a/tests/qemuxmlconfdata/pcie-root-port-speed-width.x86_64-latest.args 
b/tests/qemuxmlconfdata/pcie-root-port-speed-width.x86_64-latest.args
new file mode 100644
index 0000000000..a31e0903bc
--- /dev/null
+++ b/tests/qemuxmlconfdata/pcie-root-port-speed-width.x86_64-latest.args
@@ -0,0 +1,37 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-guest \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=guest,debug-threads=on \
+-S \
+-object 
'{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}'
 \
+-machine q35,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=2097152k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":2147483648}' \
+-overcommit mem-lock=off \
+-smp 2,sockets=2,cores=1,threads=1 \
+-uuid 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=@mon-fd@,server=on,wait=off \
+-object '{"qom-type":"monitor-qmp","id":"monitor","chardev":"charmonitor"}' \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device 
'{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x1"}'
 \
+-device 
'{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","speed":"16","width":"8","bus":"pcie.0","addr":"0x1.0x1"}'
 \
+-device 
'{"driver":"ioh3420","port":10,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x1.0x2"}'
 \
+-device '{"driver":"qemu-xhci","id":"usb","bus":"pci.1","addr":"0x0"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-global ICH9-LPC.noreboot=off \
+-watchdog-action reset \
+-sandbox 
on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/pcie-root-port-speed-width.x86_64-latest.xml 
b/tests/qemuxmlconfdata/pcie-root-port-speed-width.x86_64-latest.xml
new file mode 100644
index 0000000000..cf6e0f936f
--- /dev/null
+++ b/tests/qemuxmlconfdata/pcie-root-port-speed-width.x86_64-latest.xml
@@ -0,0 +1,48 @@
+<domain type='qemu'>
+  <name>guest</name>
+  <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid>
+  <memory unit='KiB'>2097152</memory>
+  <currentMemory unit='KiB'>2097152</currentMemory>
+  <vcpu placement='static'>2</vcpu>
+  <os>
+    <type arch='x86_64' machine='q35'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <cpu mode='custom' match='exact' check='none'>
+    <model fallback='forbid'>qemu64</model>
+  </cpu>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <controller type='pci' index='0' model='pcie-root'/>
+    <controller type='pci' index='1' model='pcie-root-port'>
+      <model name='pcie-root-port'/>
+      <target chassis='1' port='0x8'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' 
function='0x0' multifunction='on'/>
+    </controller>
+    <controller type='pci' index='2' model='pcie-root-port'>
+      <model name='pcie-root-port'/>
+      <target chassis='2' port='0x9' speed='16' width='8'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' 
function='0x1'/>
+    </controller>
+    <controller type='pci' index='3' model='pcie-root-port'>
+      <model name='ioh3420'/>
+      <target chassis='3' port='0xa'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' 
function='0x2'/>
+    </controller>
+    <controller type='usb' index='0' model='qemu-xhci'>
+      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' 
function='0x0'/>
+    </controller>
+    <controller type='sata' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' 
function='0x2'/>
+    </controller>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <audio id='1' type='none'/>
+    <watchdog model='itco' action='reset'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/pcie-root-port-speed-width.xml 
b/tests/qemuxmlconfdata/pcie-root-port-speed-width.xml
new file mode 100644
index 0000000000..5581730709
--- /dev/null
+++ b/tests/qemuxmlconfdata/pcie-root-port-speed-width.xml
@@ -0,0 +1,23 @@
+<domain type='qemu'>
+  <name>guest</name>
+  <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid>
+  <memory unit='KiB'>2097152</memory>
+  <currentMemory unit='KiB'>2097152</currentMemory>
+  <vcpu placement='static'>2</vcpu>
+  <os>
+    <type arch='x86_64' machine='q35'>hvm</type>
+  </os>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <controller type='pci' index='0' model='pcie-root'/>
+    <controller type='pci' index='1' model='pcie-root-port'/>
+    <controller type='pci' index='2' model='pcie-root-port'>
+      <model name='pcie-root-port'/>
+      <target speed='16' width='8'/>
+    </controller>
+    <controller type='pci' index='3' model='pcie-root-port'>
+      <model name='ioh3420'/>
+    </controller>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git 
a/tests/qemuxmlconfdata/pcie-switch-downstream-port-model-generic.x86_64-latest.args
 
b/tests/qemuxmlconfdata/pcie-switch-downstream-port-model-generic.x86_64-latest.args
index 39a2a98fa1..fc304392c3 100644
--- 
a/tests/qemuxmlconfdata/pcie-switch-downstream-port-model-generic.x86_64-latest.args
+++ 
b/tests/qemuxmlconfdata/pcie-switch-downstream-port-model-generic.x86_64-latest.args
@@ -31,7 +31,7 @@ 
XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.config \
 -device 
'{"driver":"xio3130-downstream","port":0,"chassis":3,"id":"pci.3","bus":"pci.2","addr":"0x0"}'
 \
 -device 
'{"driver":"xio3130-downstream","port":1,"chassis":4,"id":"pci.4","bus":"pci.2","addr":"0x1"}'
 \
 -device 
'{"driver":"xio3130-downstream","port":2,"chassis":5,"id":"pci.5","bus":"pci.2","addr":"0x2"}'
 \
--device 
'{"driver":"pcie-downstream-port","port":39,"chassis":30,"id":"pci.6","bus":"pci.2","addr":"0x3"}'
 \
+-device 
'{"driver":"pcie-downstream-port","port":39,"chassis":30,"id":"pci.6","speed":"16","width":"8","bus":"pci.2","addr":"0x3"}'
 \
 -device '{"driver":"x3130-upstream","id":"pci.7","bus":"pci.3","addr":"0x0"}' \
 -device 
'{"driver":"xio3130-downstream","port":4,"chassis":8,"id":"pci.8","bus":"pci.2","addr":"0x4"}'
 \
 -device 
'{"driver":"xio3130-downstream","port":5,"chassis":9,"id":"pci.9","bus":"pci.2","addr":"0x5"}'
 \
diff --git 
a/tests/qemuxmlconfdata/pcie-switch-downstream-port-model-generic.x86_64-latest.xml
 
b/tests/qemuxmlconfdata/pcie-switch-downstream-port-model-generic.x86_64-latest.xml
index 0b76ecd411..0647ec83d3 100644
--- 
a/tests/qemuxmlconfdata/pcie-switch-downstream-port-model-generic.x86_64-latest.xml
+++ 
b/tests/qemuxmlconfdata/pcie-switch-downstream-port-model-generic.x86_64-latest.xml
@@ -50,7 +50,7 @@
     </controller>
     <controller type='pci' index='6' model='pcie-switch-downstream-port'>
       <model name='pcie-downstream-port'/>
-      <target chassis='30' port='0x27'/>
+      <target chassis='30' port='0x27' speed='16' width='8'/>
       <address type='pci' domain='0x0000' bus='0x02' slot='0x03' 
function='0x0'/>
     </controller>
     <controller type='pci' index='7' model='pcie-switch-upstream-port'>
diff --git 
a/tests/qemuxmlconfdata/pcie-switch-downstream-port-model-generic.xml 
b/tests/qemuxmlconfdata/pcie-switch-downstream-port-model-generic.xml
index 19d5e96233..d0cb8e9939 100644
--- a/tests/qemuxmlconfdata/pcie-switch-downstream-port-model-generic.xml
+++ b/tests/qemuxmlconfdata/pcie-switch-downstream-port-model-generic.xml
@@ -27,7 +27,7 @@
     <controller type='pci' index='5' model='pcie-switch-downstream-port'/>
     <controller type='pci' index='6' model='pcie-switch-downstream-port'>
       <model name='pcie-downstream-port'/>
-      <target chassis='30' port='0x27'/>
+      <target chassis='30' port='0x27' speed='16' width='8'/>
     </controller>
     <controller type='pci' index='7' model='pcie-switch-upstream-port'/>
     <controller type='pci' index='8' model='pcie-switch-downstream-port'/>
diff --git 
a/tests/qemuxmlconfdata/pcie-switch-upstream-port-model-generic.x86_64-latest.args
 
b/tests/qemuxmlconfdata/pcie-switch-upstream-port-model-generic.x86_64-latest.args
index bd5d3541c2..f99be00a95 100644
--- 
a/tests/qemuxmlconfdata/pcie-switch-upstream-port-model-generic.x86_64-latest.args
+++ 
b/tests/qemuxmlconfdata/pcie-switch-upstream-port-model-generic.x86_64-latest.args
@@ -29,7 +29,7 @@ 
XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.config \
 -device 
'{"driver":"pcie-root-port","port":16,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x2"}'
 \
 -device 
'{"driver":"pcie-root-port","port":17,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x2.0x1"}'
 \
 -device '{"driver":"x3130-upstream","id":"pci.3","bus":"pci.1","addr":"0x0"}' \
--device 
'{"driver":"pcie-upstream-port","id":"pci.4","bus":"pci.2","addr":"0x0"}' \
+-device 
'{"driver":"pcie-upstream-port","id":"pci.4","speed":"16","width":"8","bus":"pci.2","addr":"0x0"}'
 \
 -device 
'{"driver":"pcie-root-port","port":18,"chassis":5,"id":"pci.5","bus":"pcie.0","addr":"0x2.0x2"}'
 \
 -device '{"driver":"qemu-xhci","id":"usb","bus":"pci.5","addr":"0x0"}' \
 -blockdev 
'{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","read-only":false}'
 \
diff --git 
a/tests/qemuxmlconfdata/pcie-switch-upstream-port-model-generic.x86_64-latest.xml
 
b/tests/qemuxmlconfdata/pcie-switch-upstream-port-model-generic.x86_64-latest.xml
index 07cc8947c2..7749c07f9e 100644
--- 
a/tests/qemuxmlconfdata/pcie-switch-upstream-port-model-generic.x86_64-latest.xml
+++ 
b/tests/qemuxmlconfdata/pcie-switch-upstream-port-model-generic.x86_64-latest.xml
@@ -40,6 +40,7 @@
     </controller>
     <controller type='pci' index='4' model='pcie-switch-upstream-port'>
       <model name='pcie-upstream-port'/>
+      <target speed='16' width='8'/>
       <address type='pci' domain='0x0000' bus='0x02' slot='0x00' 
function='0x0'/>
     </controller>
     <controller type='pci' index='5' model='pcie-root-port'>
diff --git a/tests/qemuxmlconfdata/pcie-switch-upstream-port-model-generic.xml 
b/tests/qemuxmlconfdata/pcie-switch-upstream-port-model-generic.xml
index d015b2631e..b46e895d41 100644
--- a/tests/qemuxmlconfdata/pcie-switch-upstream-port-model-generic.xml
+++ b/tests/qemuxmlconfdata/pcie-switch-upstream-port-model-generic.xml
@@ -25,6 +25,7 @@
     <controller type='pci' index='3' model='pcie-switch-upstream-port'/>
     <controller type='pci' index='4' model='pcie-switch-upstream-port'>
       <model name='pcie-upstream-port'/>
+      <target speed='16' width='8'/>
     </controller>
     <controller type='sata' index='0'/>
     <input type='mouse' bus='ps2'/>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 196503163f..416c9c459b 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2770,6 +2770,7 @@ mymain(void)
      * based on QEMU binary capabilities. We use x86/q35 for the test, but
      * any PCIe machine type (such as aarch64/virt) will behave the same */
     DO_TEST_CAPS_LATEST("pcie-root-port-model-generic");
+    DO_TEST_CAPS_LATEST("pcie-root-port-speed-width");
     DO_TEST_CAPS_LATEST("pcie-root-port-model-ioh3420");
     DO_TEST_CAPS_LATEST("pcie-root-port-nohotplug");
 
-- 
2.43.0

Reply via email to