summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorPeter Xu <peterx@redhat.com>2017-04-07 18:59:11 +0800
committerEduardo Habkost <ehabkost@redhat.com>2017-04-20 15:22:41 -0300
commitfaa362e3cc94bf739a89b457693e3fbd7a4b95c4 (patch)
tree1351dee21f56aad7fa67295d6fb27e18d4928ca7
parentbd2bfa4c52e5f4dc6dbaa5be0521aedc31cb53d9 (diff)
downloadfocaccia-qemu-faa362e3cc94bf739a89b457693e3fbd7a4b95c4.tar.gz
focaccia-qemu-faa362e3cc94bf739a89b457693e3fbd7a4b95c4.zip
memory: add MemoryRegionIOMMUOps.replay() callback
Originally we have one memory_region_iommu_replay() function, which is
the default behavior to replay the translations of the whole IOMMU
region. However, on some platform like x86, we may want our own replay
logic for IOMMU regions. This patch adds one more hook for IOMMUOps for
the callback, and it'll override the default if set.

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: \"Michael S. Tsirkin\" <mst@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Message-Id: <1491562755-23867-6-git-send-email-peterx@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
-rw-r--r--include/exec/memory.h2
-rw-r--r--memory.c6
2 files changed, 8 insertions, 0 deletions
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 055b3a8b23..c0280b7064 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -191,6 +191,8 @@ struct MemoryRegionIOMMUOps {
     void (*notify_flag_changed)(MemoryRegion *iommu,
                                 IOMMUNotifierFlag old_flags,
                                 IOMMUNotifierFlag new_flags);
+    /* Set this up to provide customized IOMMU replay function */
+    void (*replay)(MemoryRegion *iommu, IOMMUNotifier *notifier);
 };
 
 typedef struct CoalescedMemoryRange CoalescedMemoryRange;
diff --git a/memory.c b/memory.c
index ded4bf13d6..b782d5bc5a 100644
--- a/memory.c
+++ b/memory.c
@@ -1626,6 +1626,12 @@ void memory_region_iommu_replay(MemoryRegion *mr, IOMMUNotifier *n,
     hwaddr addr, granularity;
     IOMMUTLBEntry iotlb;
 
+    /* If the IOMMU has its own replay callback, override */
+    if (mr->iommu_ops->replay) {
+        mr->iommu_ops->replay(mr, n);
+        return;
+    }
+
     granularity = memory_region_iommu_get_min_page_size(mr);
 
     for (addr = 0; addr < memory_region_size(mr); addr += granularity) {