diff mbox series

[ats_vtd,v1,14/24] pci: add IOMMU operations to get address spaces and memory regions with PASID

Message ID 20240502152810.187492-15-clement.mathieu--drif@eviden.com
State New
Headers show
Series ATS support for VT-d | expand

Commit Message

CLEMENT MATHIEU--DRIF May 2, 2024, 3:29 p.m. UTC
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(+)

Comments

Duan, Zhenzhong May 14, 2024, 9:20 a.m. UTC | #1
>-----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 mbox series

Patch

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);