qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 2/5] pci: Add interface names to hybrid PCI devi


From: Marcel Apfelbaum
Subject: Re: [Qemu-devel] [PATCH 2/5] pci: Add interface names to hybrid PCI devices
Date: Sun, 27 Aug 2017 11:33:46 +0300
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:52.0) Gecko/20100101 Thunderbird/52.1.1

Hi Eduardo,

On 25/08/2017 22:18, Eduardo Habkost wrote:
On Wed, Aug 23, 2017 at 07:14:42PM -0300, Eduardo Habkost wrote:
The following devices support both PCIe and legacy PCI, by
including special code to handle the QEMU_PCI_CAP_EXPRESS flag:

* vfio-pci (is_express=1, but legacy PCI handled by
   vfio_populate_device())
* vmxnet3 (is_express=0, but PCIe handled by vmxnet3_realize())
* pvscsi (is_express=0, but PCIe handled by pvscsi_realize())
* virtio-pci (is_express=0, but PCIe handled by
   virtio_pci_dc_realize(), and additional legacy PCI code at
   virtio_pci_realize())

Oh, the rules are even messier than that: QEMU_PCI_CAP_EXPRESS
controls _some_ of the code that makes a device become a PCI
Express device, but not every case.

In addition to vmxnet3, pvscsi and virtio-pci, PCIe caps
initialization is conditional on hcd-xhci (see below).

This means xhci is also a hybrid device.  But it doesn't seem to
clear QEMU_PCI_CAP_EXPRESS.  Doesn't it mean pci_config_size() is
broken if xhci is plugged to a legacy PCI bus?  How does it
affect migration?


If this is the case we reserve more config space than needed.
Other than wasted space it should be OK, including migration.

Thanks,
Marcel

Full list of pci_endpoint_cap*_init() calls:

hw/usb/hcd-xhci.c-    if (pci_bus_is_express(dev->bus) ||
hw/usb/hcd-xhci.c-        xhci_get_flag(xhci, XHCI_FLAG_FORCE_PCIE_ENDCAP)) {
hw/usb/hcd-xhci.c:        ret = pcie_endpoint_cap_init(dev, 0xa0);

hw/net/vmxnet3.c-    if (pci_is_express(pci_dev)) {
hw/net/vmxnet3.c-        if (pci_bus_is_express(pci_dev->bus)) {
hw/net/vmxnet3.c:            pcie_endpoint_cap_init(pci_dev, 
VMXNET3_EXP_EP_OFFSET);
hw/net/vmxnet3.c-        }

hw/scsi/megasas.c-    if (pci_is_express(dev)) {
hw/scsi/megasas.c:        pcie_endpoint_cap_init(dev, 0xa0);
hw/scsi/megasas.c-    }

hw/scsi/vmw_pvscsi.c-    if (pci_is_express(pci_dev) && 
pci_bus_is_express(pci_dev->bus)) {
hw/scsi/vmw_pvscsi.c:        pcie_endpoint_cap_init(pci_dev, 
PVSCSI_EXP_EP_OFFSET);
hw/scsi/vmw_pvscsi.c-    }

hw/virtio/virtio-pci.c-    if (pcie_port && pci_is_express(pci_dev)) {
hw/virtio/virtio-pci.c-        int pos;
hw/virtio/virtio-pci.c-
hw/virtio/virtio-pci.c:        pos = pcie_endpoint_cap_init(pci_dev, 0);


Note: on megasas, pci_endpoitn_cap_init() is conditional on
pci_is_express(), but pci_is_express() will never be false on
megasas-gen2 (because QEMU_PCI_CAP_EXPRESS is always set).


Full list of unconditional pci_endpoint_cap*init() calls:

hw/block/nvme.c:    pcie_endpoint_cap_init(&n->parent_obj, 0x80);

hw/net/e1000e.c:    if (pcie_endpoint_cap_v1_init(pci_dev, e1000e_pcie_offset) 
< 0) {

hw/pci-bridge/pcie_root_port.c:    rc = pcie_cap_init(d, rpc->exp_offset, 
PCI_EXP_TYPE_ROOT_PORT,
hw/pci-bridge/pcie_root_port.c-                       p->port, errp);

hw/pci-bridge/xio3130_downstream.c:    rc = pcie_cap_init(d, 
XIO3130_EXP_OFFSET, PCI_EXP_TYPE_DOWNSTREAM,
hw/pci-bridge/xio3130_downstream.c-                       p->port, errp);

hw/pci-bridge/xio3130_upstream.c:    rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, 
PCI_EXP_TYPE_UPSTREAM,
hw/pci-bridge/xio3130_upstream.c-                       p->port, errp);

hw/pci-host/xilinx-pcie.c:    if (pcie_endpoint_cap_v1_init(dev, 0x80) < 0) {




Signed-off-by: Eduardo Habkost <address@hidden>
---
  hw/net/vmxnet3.c       | 5 +++++
  hw/scsi/vmw_pvscsi.c   | 2 ++
  hw/vfio/pci.c          | 5 +++++
  hw/virtio/virtio-pci.c | 5 +++++
  4 files changed, 17 insertions(+)

diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index a19a7a3..61feacf 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -2651,6 +2651,11 @@ static const TypeInfo vmxnet3_info = {
      .instance_size = sizeof(VMXNET3State),
      .class_init    = vmxnet3_class_init,
      .instance_init = vmxnet3_instance_init,
+    .interfaces = (InterfaceInfo[]) {
+        { INTERFACE_PCIE_DEVICE },
+        { INTERFACE_LEGACY_PCI_DEVICE },
+        { }
+    },
  };
static void vmxnet3_register_types(void)
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 77d8b6f..40dfffa 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -1300,6 +1300,8 @@ static const TypeInfo pvscsi_info = {
      .class_init    = pvscsi_class_init,
      .interfaces = (InterfaceInfo[]) {
          { TYPE_HOTPLUG_HANDLER },
+        { INTERFACE_PCIE_DEVICE },
+        { INTERFACE_LEGACY_PCI_DEVICE },
          { }
      }
  };
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 31e1edf..2b21391 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3023,6 +3023,11 @@ static const TypeInfo vfio_pci_dev_info = {
      .class_init = vfio_pci_dev_class_init,
      .instance_init = vfio_instance_init,
      .instance_finalize = vfio_instance_finalize,
+    .interfaces = (InterfaceInfo[]) {
+        { INTERFACE_PCIE_DEVICE },
+        { INTERFACE_LEGACY_PCI_DEVICE },
+        { }
+    },
  };
static void register_vfio_pci_dev_type(void)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 8b0d6b6..8c0b6bf 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1958,6 +1958,11 @@ static const TypeInfo virtio_pci_info = {
      .class_init    = virtio_pci_class_init,
      .class_size    = sizeof(VirtioPCIClass),
      .abstract      = true,
+    .interfaces = (InterfaceInfo[]) {
+        { INTERFACE_PCIE_DEVICE },
+        { INTERFACE_LEGACY_PCI_DEVICE },
+        { }
+    },
  };
/* virtio-blk-pci */
--
2.9.4







reply via email to

[Prev in Thread] Current Thread [Next in Thread]