@@ -2747,6 +2747,25 @@ AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
return &address_space_memory;
}
+AddressSpace *pci_device_iommu_address_space_pasid(PCIDevice *dev,
+ uint32_t pasid)
+{
+ PCIBus *bus;
+ PCIBus *iommu_bus;
+ int devfn;
+
+ if (!dev->is_master || !pcie_pasid_enabled(dev) || pasid == PCI_NO_PASID) {
+ return NULL;
+ }
+
+ pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn);
+ if (iommu_bus && iommu_bus->iommu_ops->get_address_space_pasid) {
+ return iommu_bus->iommu_ops->get_address_space_pasid(bus,
+ iommu_bus->iommu_opaque, devfn, pasid);
+ }
+ return NULL;
+}
+
bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod,
Error **errp)
{
@@ -385,6 +385,38 @@ typedef struct PCIIOMMUOps {
* @devfn: device and function number
*/
AddressSpace * (*get_address_space)(PCIBus *bus, void *opaque, int devfn);
+ /**
+ * @get_address_space_pasid: same as get_address_space but returns an
+ * address space with the requested PASID
+ *
+ * This callback is required for PASID-based operations
+ *
+ * @bus: the #PCIBus being accessed.
+ *
+ * @opaque: the data passed to pci_setup_iommu().
+ *
+ * @devfn: device and function number
+ *
+ * @pasid: the pasid associated with the requested memory region
+ */
+ AddressSpace * (*get_address_space_pasid)(PCIBus *bus, void *opaque,
+ int devfn, uint32_t pasid);
+ /**
+ * @get_memory_region_pasid: get the iommu memory region for a given
+ * device and pasid
+ *
+ * @bus: the #PCIBus being accessed.
+ *
+ * @opaque: the data passed to pci_setup_iommu().
+ *
+ * @devfn: device and function number
+ *
+ * @pasid: the pasid associated with the requested memory region
+ */
+ IOMMUMemoryRegion * (*get_memory_region_pasid)(PCIBus *bus,
+ void *opaque,
+ int devfn,
+ uint32_t pasid);
/**
* @set_iommu_device: attach a HostIOMMUDevice to a vIOMMU
*
@@ -420,6 +452,8 @@ typedef struct PCIIOMMUOps {
} PCIIOMMUOps;
AddressSpace *pci_device_iommu_address_space(PCIDevice *dev);
+AddressSpace *pci_device_iommu_address_space_pasid(PCIDevice *dev,
+ uint32_t pasid);
bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod,
Error **errp);
void pci_device_unset_iommu_device(PCIDevice *dev);