qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH 2/2] pci: Use the new can_add_device() to enforce devfn_min/max
@ 2015-07-04 23:24 Benjamin Herrenschmidt
  0 siblings, 0 replies; only message in thread
From: Benjamin Herrenschmidt @ 2015-07-04 23:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Michael S. Tsirkin

This adds a devfn_max field to PCIBus and adds a pci_can_add_device()
function which, if no "addr" (aka devfn) is specified, will tell whether
there is any slot free between devfn_min and devfn_max.

This will be used by some PCI root complex implementations that support
only one direct child to avoid having qemu put dumb devices at different
slot numbers.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

I use this to avoid qemu putting devices in places they won't be probed,
for example at a non-0 dev# under my PCIe root complex (my FW will never
probe since it can't possibly happen on HW), and in fact, arguably, this
should also be done for PCIe switch downstream ports.

This is "RFC" however since there are cases with SR-IOV where we *do*
want to make things appear at dev# != 0, if we ever implement emulation
of SR-IOV that is.

Without this, qemu has a tendency to just pile up PCI devices in places
where it makes no sense to have them and they won't be probed however.

 hw/pci/pci.c             | 22 ++++++++++++++++++++++
 include/hw/pci/pci_bus.h |  1 +
 2 files changed, 23 insertions(+)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 442f822..29f0b0f 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -107,6 +107,27 @@ static uint16_t pcibus_numa_node(PCIBus *bus)
     return NUMA_NODE_UNASSIGNED;
 }
 
+static bool pci_can_add_device(BusState *bus, QemuOpts *opts)
+{
+    unsigned int devfn, max;
+    PCIBus *pbus = PCI_BUS(bus);
+
+    /* If address is specified, say yes and let it fail if that doesn't work */
+    if (qemu_opt_get(opts, "addr") != NULL) {
+        return true;
+    }
+    max = ARRAY_SIZE(pbus->devices);
+    if (pbus->devfn_max && pbus->devfn_max < max) {
+       max = pbus->devfn_max;
+    }
+    for (devfn = pbus->devfn_min ; devfn < max; devfn += PCI_FUNC_MAX) {
+        if (!pbus->devices[devfn]) {
+            break;
+        }
+    }
+    return devfn < max;
+}
+
 static void pci_bus_class_init(ObjectClass *klass, void *data)
 {
     BusClass *k = BUS_CLASS(klass);
@@ -118,6 +139,7 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
     k->realize = pci_bus_realize;
     k->unrealize = pci_bus_unrealize;
     k->reset = pcibus_reset;
+    k->can_add_device = pci_can_add_device;
 
     pbc->is_root = pcibus_is_root;
     pbc->bus_num = pcibus_num;
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index 403fec6..02055d4 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -23,6 +23,7 @@ struct PCIBus {
     PCIIOMMUFunc iommu_fn;
     void *iommu_opaque;
     uint8_t devfn_min;
+    uint8_t devfn_max;
     pci_set_irq_fn set_irq;
     pci_map_irq_fn map_irq;
     pci_route_irq_fn route_intx_to_irq;

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2015-07-04 23:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-04 23:24 [Qemu-devel] [RFC PATCH 2/2] pci: Use the new can_add_device() to enforce devfn_min/max Benjamin Herrenschmidt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).