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>
This commit is contained in:
Knut Omang 2015-10-04 15:48:50 +02:00 committed by Michael S. Tsirkin
parent 6d57410a79
commit 7df953bd45
3 changed files with 90 additions and 40 deletions

View file

@ -49,6 +49,7 @@ typedef struct VTDContextCacheEntry VTDContextCacheEntry;
typedef struct IntelIOMMUState IntelIOMMUState;
typedef struct VTDAddressSpace VTDAddressSpace;
typedef struct VTDIOTLBEntry VTDIOTLBEntry;
typedef struct VTDBus VTDBus;
/* Context-Entry */
struct VTDContextEntry {
@ -65,7 +66,7 @@ struct VTDContextCacheEntry {
};
struct VTDAddressSpace {
uint8_t bus_num;
PCIBus *bus;
uint8_t devfn;
AddressSpace as;
MemoryRegion iommu;
@ -73,6 +74,11 @@ struct VTDAddressSpace {
VTDContextCacheEntry context_cache_entry;
};
struct VTDBus {
PCIBus* bus; /* A reference to the bus to provide translation for */
VTDAddressSpace *dev_as[0]; /* A table of VTDAddressSpace objects indexed by devfn */
};
struct VTDIOTLBEntry {
uint64_t gfn;
uint16_t domain_id;
@ -114,7 +120,13 @@ struct IntelIOMMUState {
GHashTable *iotlb; /* IOTLB */
MemoryRegionIOMMUOps iommu_ops;
VTDAddressSpace **address_spaces[VTD_PCI_BUS_MAX];
GHashTable *vtd_as_by_busptr; /* VTDBus objects indexed by PCIBus* reference */
VTDBus *vtd_as_by_bus_num[VTD_PCI_BUS_MAX]; /* VTDBus objects indexed by bus number */
};
/* Find the VTD Address space associated with the given bus pointer,
* create a new one if none exists
*/
VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn);
#endif