summaryrefslogtreecommitdiffstats
path: root/hw/arm/smmu-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/arm/smmu-common.c')
-rw-r--r--hw/arm/smmu-common.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
index f66e444f6f..3098915d07 100644
--- a/hw/arm/smmu-common.c
+++ b/hw/arm/smmu-common.c
@@ -385,6 +385,40 @@ static gboolean smmu_iotlb_key_equal(gconstpointer v1, gconstpointer v2)
return (k1->asid == k2->asid) && (k1->iova == k2->iova);
}
+/* Unmap the whole notifier's range */
+static void smmu_unmap_notifier_range(IOMMUNotifier *n)
+{
+ IOMMUTLBEntry entry;
+
+ entry.target_as = &address_space_memory;
+ entry.iova = n->start;
+ entry.perm = IOMMU_NONE;
+ entry.addr_mask = n->end - n->start;
+
+ memory_region_notify_one(n, &entry);
+}
+
+/* Unmap all notifiers attached to @mr */
+inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
+{
+ IOMMUNotifier *n;
+
+ trace_smmu_inv_notifiers_mr(mr->parent_obj.name);
+ IOMMU_NOTIFIER_FOREACH(n, mr) {
+ smmu_unmap_notifier_range(n);
+ }
+}
+
+/* Unmap all notifiers of all mr's */
+void smmu_inv_notifiers_all(SMMUState *s)
+{
+ SMMUNotifierNode *node;
+
+ QLIST_FOREACH(node, &s->notifiers_list, next) {
+ smmu_inv_notifiers_mr(&node->sdev->iommu);
+ }
+}
+
static void smmu_base_realize(DeviceState *dev, Error **errp)
{
SMMUState *s = ARM_SMMU(dev);