Message ID | 20240502152810.187492-15-clement.mathieu--drif@eviden.com |
---|---|
State | New |
Headers | show |
Series | ATS support for VT-d | expand |
>-----Original Message----- >From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com> >Subject: [PATCH ats_vtd v1 14/24] pci: add IOMMU operations to get >address spaces and memory regions with PASID > >Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com> >--- > hw/pci/pci.c | 20 ++++++++++++++++++++ > include/hw/pci/pci.h | 34 ++++++++++++++++++++++++++++++++++ > 2 files changed, 54 insertions(+) > >diff --git a/hw/pci/pci.c b/hw/pci/pci.c >index e5f72f9f1d..9ed788c95d 100644 >--- a/hw/pci/pci.c >+++ b/hw/pci/pci.c >@@ -2747,6 +2747,26 @@ 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 (!pci_bus_bypass_iommu(bus) && iommu_bus->iommu_ops && This is implicitly checked in pci_device_get_iommu_bus_devfn(). Just do " if (iommu_bus) && " Thanks Zhenzhong >+ 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; >+} >+ > int pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice >*hiod, > Error **errp) > { >diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h >index 849e391813..0c532c563c 100644 >--- a/include/hw/pci/pci.h >+++ b/include/hw/pci/pci.h >@@ -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); > int pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice >*hiod, > Error **errp); > void pci_device_unset_iommu_device(PCIDevice *dev); >-- >2.44.0
diff --git a/hw/pci/pci.c b/hw/pci/pci.c index e5f72f9f1d..9ed788c95d 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -2747,6 +2747,26 @@ 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 (!pci_bus_bypass_iommu(bus) && iommu_bus->iommu_ops && + 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; +} + int pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod, Error **errp) { diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 849e391813..0c532c563c 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -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); int pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod, Error **errp); void pci_device_unset_iommu_device(PCIDevice *dev);
Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com> --- hw/pci/pci.c | 20 ++++++++++++++++++++ include/hw/pci/pci.h | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+)