qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Marcel Apfelbaum <marcel@redhat.com>
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, marcel@redhat.com, pbonzini@redhat.com,
	mst@redhat.com, davidkiarie4@gmail.com, peterx@redhat.com,
	bd.aviv@gmail.com
Subject: [Qemu-devel] [PATCH RFC 1/2] hw/pci: delay bus_master_enable_region initialization
Date: Mon, 23 May 2016 17:01:29 +0300	[thread overview]
Message-ID: <1464012090-6477-2-git-send-email-marcel@redhat.com> (raw)
In-Reply-To: <1464012090-6477-1-git-send-email-marcel@redhat.com>

Skip bus_master_enable region creation on PCI devices init
in order to be sure the IOMMU device (if present) would
be created in advance. Add this memory region at machine_done time.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/i386/pc.c         | 17 +++++++++++++++++
 hw/pci/pci.c         | 22 ++++++++++++----------
 include/hw/pci/pci.h |  2 ++
 3 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 99437e0..f9ac543 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -32,6 +32,7 @@
 #include "hw/ide.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_bus.h"
+#include "hw/pci/pci_bridge.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/timer/hpet.h"
 #include "hw/smbios/smbios.h"
@@ -1156,12 +1157,26 @@ typedef struct PcRomPciInfo {
     uint64_t w64_max;
 } PcRomPciInfo;
 
+static void pci_bus_enable_bus_master(PCIBus *bus, PCIDevice *dev, void *opaque)
+{
+    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
+
+    pci_init_bus_master(dev);
+
+    if (pc->is_bridge) {
+        PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(dev));
+        pci_for_each_device(sec_bus, pci_bus_num(sec_bus),
+                            pci_bus_enable_bus_master, opaque);
+    }
+}
+
 static
 void pc_machine_done(Notifier *notifier, void *data)
 {
     PCMachineState *pcms = container_of(notifier,
                                         PCMachineState, machine_done);
     PCIBus *bus = pcms->bus;
+    pci_for_each_device(bus, pci_bus_num(bus), pci_bus_enable_bus_master, NULL);
 
     if (bus) {
         int extra_hosts = 0;
@@ -1169,6 +1184,8 @@ void pc_machine_done(Notifier *notifier, void *data)
         QLIST_FOREACH(bus, &bus->child, sibling) {
             /* look for expander root buses */
             if (pci_bus_is_root(bus)) {
+                pci_for_each_device(bus, pci_bus_num(bus),
+                                    pci_bus_enable_bus_master, NULL);
                 extra_hosts++;
             }
         }
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index bb605ef..e22b1c8 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -828,6 +828,18 @@ static void pci_config_free(PCIDevice *pci_dev)
     g_free(pci_dev->used);
 }
 
+void pci_init_bus_master(PCIDevice *pci_dev)
+{
+    AddressSpace *dma_as = pci_device_iommu_address_space(pci_dev);
+
+    memory_region_init_alias(&pci_dev->bus_master_enable_region,
+                             OBJECT(pci_dev), "bus master",
+                             dma_as->root, 0, memory_region_size(dma_as->root));
+    memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);
+    address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region,
+                       pci_dev->name);
+}
+
 static void do_pci_unregister_device(PCIDevice *pci_dev)
 {
     pci_dev->bus->devices[pci_dev->devfn] = NULL;
@@ -845,7 +857,6 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
     PCIConfigReadFunc *config_read = pc->config_read;
     PCIConfigWriteFunc *config_write = pc->config_write;
     Error *local_err = NULL;
-    AddressSpace *dma_as;
     DeviceState *dev = DEVICE(pci_dev);
 
     pci_dev->bus = bus;
@@ -885,15 +896,6 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
     }
 
     pci_dev->devfn = devfn;
-    dma_as = pci_device_iommu_address_space(pci_dev);
-
-    memory_region_init_alias(&pci_dev->bus_master_enable_region,
-                             OBJECT(pci_dev), "bus master",
-                             dma_as->root, 0, memory_region_size(dma_as->root));
-    memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);
-    address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region,
-                       name);
-
     pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
     pci_dev->irq_state = 0;
     pci_config_alloc(pci_dev);
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index ef6ba51..95a930f 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -343,6 +343,8 @@ int pci_device_load(PCIDevice *s, QEMUFile *f);
 MemoryRegion *pci_address_space(PCIDevice *dev);
 MemoryRegion *pci_address_space_io(PCIDevice *dev);
 
+void pci_init_bus_master(PCIDevice *dev);
+
 /*
  * Should not normally be used by devices. For use by sPAPR target
  * where QEMU emulates firmware.
-- 
2.4.3

  reply	other threads:[~2016-05-23 14:01 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-23 14:01 [Qemu-devel] [PATCH RFC 0/2] enable iommu with -device Marcel Apfelbaum
2016-05-23 14:01 ` Marcel Apfelbaum [this message]
2016-05-23 14:08   ` [Qemu-devel] [PATCH RFC 1/2] hw/pci: delay bus_master_enable_region initialization Paolo Bonzini
2016-05-23 14:22     ` Marcel Apfelbaum
2016-05-23 14:33       ` Paolo Bonzini
2016-05-23 14:01 ` [Qemu-devel] [PATCH RFC 2/2] hw/iommu: enable iommu with -device Marcel Apfelbaum
2016-05-30 13:43 ` [Qemu-devel] [PATCH RFC 0/2] " Peter Xu
2016-05-30 14:14   ` Marcel Apfelbaum
2016-05-31  1:44     ` Peter Xu
2016-06-02 20:30       ` Marcel Apfelbaum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1464012090-6477-2-git-send-email-marcel@redhat.com \
    --to=marcel@redhat.com \
    --cc=bd.aviv@gmail.com \
    --cc=davidkiarie4@gmail.com \
    --cc=ehabkost@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).