Commit 18613dc6 authored by Denis V. Lunev's avatar Denis V. Lunev Committed by Dr. David Alan Gilbert
Browse files

qmp, hmp: make subsystem/system-vendor identities optional



According to PCI specification, subsystem id and subsystem vendor id
are present only in type 0 and type 2 headers (at different offsets),
but not in type 1 headers.

Thus we should make this data optional in struct PciDeviceId and skip
reporting them via HMP if the information is not available.

Additional (wrong information) about PCI bridges (Type1 devices) has been
added in 5383a705 and fortunately not released. This patch fixes that
problem. The problem was spotted by Markus.

Signed-off-by: default avatarDenis V. Lunev <den@openvz.org>
CC: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
CC: Eric Blake <eblake@redhat.com>
CC: Markus Armbruster <armbru@redhat.com>
Message-Id: <20181002135538.12113-1-den@openvz.org>
Reported-by: default avatarMarkus Armbruster <armbru@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Reviewed-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: default avatarMarkus Armbruster <armbru@redhat.com>
Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
parent 5ce43896
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -837,8 +837,10 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)

    monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n",
                   dev->id->vendor, dev->id->device);
    if (dev->id->has_subsystem_vendor && dev->id->has_subsystem) {
        monitor_printf(mon, "      PCI subsystem %04" PRIx64 ":%04" PRIx64 "\n",
                       dev->id->subsystem_vendor, dev->id->subsystem);
    }

    if (dev->has_irq) {
        monitor_printf(mon, "      IRQ %" PRId64 ".\n", dev->irq);
+10 −3
Original line number Diff line number Diff line
@@ -1737,9 +1737,6 @@ static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
    info->id = g_new0(PciDeviceId, 1);
    info->id->vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
    info->id->device = pci_get_word(dev->config + PCI_DEVICE_ID);
    info->id->subsystem = pci_get_word(dev->config + PCI_SUBSYSTEM_ID);
    info->id->subsystem_vendor =
        pci_get_word(dev->config + PCI_SUBSYSTEM_VENDOR_ID);
    info->regions = qmp_query_pci_regions(dev);
    info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");

@@ -1752,6 +1749,16 @@ static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
    if (type == PCI_HEADER_TYPE_BRIDGE) {
        info->has_pci_bridge = true;
        info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
    } else if (type == PCI_HEADER_TYPE_NORMAL) {
        info->id->has_subsystem = info->id->has_subsystem_vendor = true;
        info->id->subsystem = pci_get_word(dev->config + PCI_SUBSYSTEM_ID);
        info->id->subsystem_vendor =
            pci_get_word(dev->config + PCI_SUBSYSTEM_VENDOR_ID);
    } else if (type == PCI_HEADER_TYPE_CARDBUS) {
        info->id->has_subsystem = info->id->has_subsystem_vendor = true;
        info->id->subsystem = pci_get_word(dev->config + PCI_CB_SUBSYSTEM_ID);
        info->id->subsystem_vendor =
            pci_get_word(dev->config + PCI_CB_SUBSYSTEM_VENDOR_ID);
    }

    return info;
+2 −2
Original line number Diff line number Diff line
@@ -839,8 +839,8 @@
# Since: 2.4
##
{ 'struct': 'PciDeviceId',
  'data': {'device': 'int', 'vendor': 'int', 'subsystem': 'int',
            'subsystem-vendor': 'int'} }
  'data': {'device': 'int', 'vendor': 'int', '*subsystem': 'int',
            '*subsystem-vendor': 'int'} }

##
# @PciDeviceInfo: