On 4/9/25 15:48, John Levon wrote:
Pass through the MemoryRegion to DMA operation handlers of vfio
containers. The vfio-user container will need this later.

Originally-by: John Johnson <john.g.john...@oracle.com>
Signed-off-by: Jagannathan Raman <jag.ra...@oracle.com>
Signed-off-by: Elena Ufimtseva <elena.ufimts...@oracle.com>
Signed-off-by: John Levon <john.le...@nutanix.com>
---
  hw/vfio/container-base.c              |  4 ++--
  hw/vfio/container.c                   |  3 ++-
  hw/vfio/iommufd.c                     |  3 ++-
  hw/vfio/listener.c                    | 18 +++++++++++-------
  hw/virtio/vhost-vdpa.c                |  2 +-
  include/exec/memory.h                 |  4 +++-
  include/hw/vfio/vfio-container-base.h |  4 ++--
  system/memory.c                       |  7 ++++++-
  8 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c
index 16fe5f79d2..55c977ec33 100644
--- a/hw/vfio/container-base.c
+++ b/hw/vfio/container-base.c
@@ -75,12 +75,12 @@ void vfio_address_space_insert(VFIOAddressSpace *space,
int vfio_container_dma_map(VFIOContainerBase *bcontainer,
                             hwaddr iova, ram_addr_t size,
-                           void *vaddr, bool readonly)
+                           void *vaddr, bool readonly, MemoryRegion *mrp)
  {
      VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
g_assert(vioc->dma_map);
-    return vioc->dma_map(bcontainer, iova, size, vaddr, readonly);
+    return vioc->dma_map(bcontainer, iova, size, vaddr, readonly, mrp);
  }
int vfio_container_dma_unmap(VFIOContainerBase *bcontainer,
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 61333d7fc4..587af60e57 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -215,7 +215,8 @@ static int vfio_legacy_dma_unmap(const VFIOContainerBase 
*bcontainer,
  }
static int vfio_legacy_dma_map(const VFIOContainerBase *bcontainer, hwaddr iova,
-                               ram_addr_t size, void *vaddr, bool readonly)
+                               ram_addr_t size, void *vaddr, bool readonly,
+                               MemoryRegion *mrp)
  {
      const VFIOContainer *container = container_of(bcontainer, VFIOContainer,
                                                    bcontainer);
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 22e5b16967..4fd3c0d9f3 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -34,7 +34,8 @@
              TYPE_HOST_IOMMU_DEVICE_IOMMUFD "-vfio"
static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova,
-                            ram_addr_t size, void *vaddr, bool readonly)
+                            ram_addr_t size, void *vaddr, bool readonly,
+                            MemoryRegion *mrp)
  {
      const VFIOIOMMUFDContainer *container =
          container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer);
diff --git a/hw/vfio/listener.c b/hw/vfio/listener.c
index 7ea9e0dfb7..cb06a63a0c 100644
--- a/hw/vfio/listener.c
+++ b/hw/vfio/listener.c
@@ -94,12 +94,12 @@ static bool 
vfio_listener_skipped_section(MemoryRegionSection *section)
  /* Called with rcu_read_lock held.  */
  static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
                                 ram_addr_t *ram_addr, bool *read_only,
-                               Error **errp)
+                               MemoryRegion **mrp, Error **errp)
  {
      bool ret, mr_has_discard_manager;
ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
-                               &mr_has_discard_manager, errp);
+                               &mr_has_discard_manager, mrp, errp);
      if (ret && mr_has_discard_manager) {
          /*
           * Malicious VMs might trigger discarding of IOMMU-mapped memory. The
@@ -127,6 +127,7 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
      VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n);
      VFIOContainerBase *bcontainer = giommu->bcontainer;
      hwaddr iova = iotlb->iova + giommu->iommu_offset;
+    MemoryRegion *mrp;
      void *vaddr;
      int ret;
      Error *local_err = NULL;
@@ -151,7 +152,8 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
      if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
          bool read_only;
- if (!vfio_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, &local_err)) {
+        if (!vfio_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, &mrp,
+                                &local_err)) {
              error_report_err(local_err);
              goto out;
          }
@@ -164,7 +166,7 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
           */
          ret = vfio_container_dma_map(bcontainer, iova,
                                       iotlb->addr_mask + 1, vaddr,
-                                     read_only);
+                                     read_only, mrp);
          if (ret) {
              error_report("vfio_container_dma_map(%p, 0x%"HWADDR_PRIx", "
                           "0x%"HWADDR_PRIx", %p) = %d (%s)",
@@ -234,7 +236,7 @@ static int 
vfio_ram_discard_notify_populate(RamDiscardListener *rdl,
          vaddr = memory_region_get_ram_ptr(section->mr) + start;
ret = vfio_container_dma_map(bcontainer, iova, next - start,
-                                     vaddr, section->readonly);
+                                     vaddr, section->readonly, section->mr);
          if (ret) {
              /* Rollback */
              vfio_ram_discard_notify_discard(rdl, section);
@@ -558,7 +560,7 @@ static void vfio_listener_region_add(MemoryListener 
*listener,
      }
ret = vfio_container_dma_map(bcontainer, iova, int128_get64(llsize),
-                                 vaddr, section->readonly);
+                                 vaddr, section->readonly, section->mr);
      if (ret) {
          error_setg(&err, "vfio_container_dma_map(%p, 0x%"HWADDR_PRIx", "
                     "0x%"HWADDR_PRIx", %p) = %d (%s)",
@@ -1022,7 +1024,9 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
      }
rcu_read_lock();
-    if (!vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL, &local_err)) {
+    if (!vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL, NULL,
+                            &local_err)) {
+        error_report_err(local_err);
          goto out_unlock;
      }
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 7efbde3d4c..eb02b081d4 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -228,7 +228,7 @@ static void vhost_vdpa_iommu_map_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
      if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
          bool read_only;
- if (!memory_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, NULL,
+        if (!memory_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, NULL, NULL,
                                    &local_err)) {
              error_report_err(local_err);
              return;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index d09af58c97..f79ff332b5 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -747,13 +747,15 @@ void 
ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
   * @read_only: indicates if writes are allowed
   * @mr_has_discard_manager: indicates memory is controlled by a
   *                          RamDiscardManager
+ * @mrp: if non-NULL, fill in with MemoryRegion
   * @errp: pointer to Error*, to store an error if it happens.
   *
   * Return: true on success, else false setting @errp with error.
   */
  bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
                            ram_addr_t *ram_addr, bool *read_only,
-                          bool *mr_has_discard_manager, Error **errp);
+                          bool *mr_has_discard_manager, MemoryRegion **mrp,
+                          Error **errp);
typedef struct CoalescedMemoryRange CoalescedMemoryRange;
  typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
diff --git a/include/hw/vfio/vfio-container-base.h 
b/include/hw/vfio/vfio-container-base.h
index 6eaf2b2430..47ce016d8e 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -78,7 +78,7 @@ void vfio_address_space_insert(VFIOAddressSpace *space,
int vfio_container_dma_map(VFIOContainerBase *bcontainer,
                             hwaddr iova, ram_addr_t size,
-                           void *vaddr, bool readonly);
+                           void *vaddr, bool readonly, MemoryRegion *mrp);
  int vfio_container_dma_unmap(VFIOContainerBase *bcontainer,
                               hwaddr iova, ram_addr_t size,
                               IOMMUTLBEntry *iotlb, int flags);
@@ -124,7 +124,7 @@ struct VFIOIOMMUClass {
      void (*listener_commit)(VFIOContainerBase *bcontainer);
      int (*dma_map)(const VFIOContainerBase *bcontainer,
                     hwaddr iova, ram_addr_t size,
-                   void *vaddr, bool readonly);
+                   void *vaddr, bool readonly, MemoryRegion *mrp);
      int (*dma_unmap)(const VFIOContainerBase *bcontainer,
                       hwaddr iova, ram_addr_t size,
                       IOMMUTLBEntry *iotlb, int flags);
diff --git a/system/memory.c b/system/memory.c
index 4c829793a0..de4f955a66 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -2185,7 +2185,8 @@ void 
ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
  /* Called with rcu_read_lock held.  */
  bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
                            ram_addr_t *ram_addr, bool *read_only,
-                          bool *mr_has_discard_manager, Error **errp)
+                          bool *mr_has_discard_manager, MemoryRegion **mrp,
+                          Error **errp)
  {
      MemoryRegion *mr;
      hwaddr xlat;
@@ -2250,6 +2251,10 @@ bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void 
**vaddr,
          *read_only = !writable || mr->readonly;
      }
+ if (mrp != NULL) {
+        *mrp = mr;
+    }
+
      return true;
  }

Is everyone OK with adding an extra in/out parameter to memory_get_xlat_addr() ?
Should we take a ref on the region ?

I think this change should be proposed in its own patch as done in the previous
series and by Steve for live update.


Thanks,

C.



Reply via email to