diff options
Diffstat (limited to 'hw/arm/smmu-common.c')
-rw-r--r-- | hw/arm/smmu-common.c | 34 |
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); |