diff options
author | Knut Omang <knut.omang@oracle.com> | 2015-10-04 15:48:50 +0200 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2015-10-18 10:05:43 +0300 |
commit | 7df953bd456da45f761064974820ab5c3fd7b2aa (patch) | |
tree | 019a1f6e52d28c39082aa40b79598e0b581ffefc /hw/pci-host/q35.c | |
parent | 6d57410a79d51d92673c54f26624b44f27fa6214 (diff) |
intel_iommu: Add support for translation for devices behind bridges
- Use a hash table indexed on bus pointers to store information about buses
instead of using the bus numbers.
Bus pointers are stored in a new VTDBus struct together with the vector
of device address space pointers indexed by devfn.
- The bus number is still used for lookup for selective SID based invalidate,
in which case the bus number is lazily resolved from the bus hash table and
cached in a separate index.
Signed-off-by: Knut Omang <knut.omang@oracle.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/pci-host/q35.c')
-rw-r--r-- | hw/pci-host/q35.c | 25 |
1 files changed, 3 insertions, 22 deletions
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index bd7409456f..c81507d710 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -426,31 +426,12 @@ static void mch_reset(DeviceState *qdev) static AddressSpace *q35_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) { IntelIOMMUState *s = opaque; - VTDAddressSpace **pvtd_as; - int bus_num = pci_bus_num(bus); + VTDAddressSpace *vtd_as; - assert(0 <= bus_num && bus_num <= VTD_PCI_BUS_MAX); assert(0 <= devfn && devfn <= VTD_PCI_DEVFN_MAX); - pvtd_as = s->address_spaces[bus_num]; - if (!pvtd_as) { - /* No corresponding free() */ - pvtd_as = g_malloc0(sizeof(VTDAddressSpace *) * VTD_PCI_DEVFN_MAX); - s->address_spaces[bus_num] = pvtd_as; - } - if (!pvtd_as[devfn]) { - pvtd_as[devfn] = g_malloc0(sizeof(VTDAddressSpace)); - - pvtd_as[devfn]->bus_num = (uint8_t)bus_num; - pvtd_as[devfn]->devfn = (uint8_t)devfn; - pvtd_as[devfn]->iommu_state = s; - pvtd_as[devfn]->context_cache_entry.context_cache_gen = 0; - memory_region_init_iommu(&pvtd_as[devfn]->iommu, OBJECT(s), - &s->iommu_ops, "intel_iommu", UINT64_MAX); - address_space_init(&pvtd_as[devfn]->as, - &pvtd_as[devfn]->iommu, "intel_iommu"); - } - return &pvtd_as[devfn]->as; + vtd_as = vtd_find_add_as(s, bus, devfn); + return &vtd_as->as; } static void mch_init_dmar(MCHPCIState *mch) |