diff options
Diffstat (limited to 'softmmu/memory.c')
-rw-r--r-- | softmmu/memory.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/softmmu/memory.c b/softmmu/memory.c index 11ca94d037..22bacbbc78 100644 --- a/softmmu/memory.c +++ b/softmmu/memory.c @@ -1942,11 +1942,16 @@ void memory_region_unregister_iommu_notifier(MemoryRegion *mr, memory_region_update_iommu_notify_flags(iommu_mr, NULL); } -void memory_region_notify_one(IOMMUNotifier *notifier, - IOMMUTLBEntry *entry) +void memory_region_notify_iommu_one(IOMMUNotifier *notifier, + IOMMUTLBEvent *event) { - IOMMUNotifierFlag request_flags; + IOMMUTLBEntry *entry = &event->entry; hwaddr entry_end = entry->iova + entry->addr_mask; + IOMMUTLBEntry tmp = *entry; + + if (event->type == IOMMU_NOTIFIER_UNMAP) { + assert(entry->perm == IOMMU_NONE); + } /* * Skip the notification if the notification does not overlap @@ -1956,22 +1961,22 @@ void memory_region_notify_one(IOMMUNotifier *notifier, return; } - assert(entry->iova >= notifier->start && entry_end <= notifier->end); - - if (entry->perm & IOMMU_RW) { - request_flags = IOMMU_NOTIFIER_MAP; + if (notifier->notifier_flags & IOMMU_NOTIFIER_DEVIOTLB_UNMAP) { + /* Crop (iova, addr_mask) to range */ + tmp.iova = MAX(tmp.iova, notifier->start); + tmp.addr_mask = MIN(entry_end, notifier->end) - tmp.iova; } else { - request_flags = IOMMU_NOTIFIER_UNMAP; + assert(entry->iova >= notifier->start && entry_end <= notifier->end); } - if (notifier->notifier_flags & request_flags) { - notifier->notify(notifier, entry); + if (event->type & notifier->notifier_flags) { + notifier->notify(notifier, &tmp); } } void memory_region_notify_iommu(IOMMUMemoryRegion *iommu_mr, int iommu_idx, - IOMMUTLBEntry entry) + IOMMUTLBEvent event) { IOMMUNotifier *iommu_notifier; @@ -1979,7 +1984,7 @@ void memory_region_notify_iommu(IOMMUMemoryRegion *iommu_mr, IOMMU_NOTIFIER_FOREACH(iommu_notifier, iommu_mr) { if (iommu_notifier->iommu_idx == iommu_idx) { - memory_region_notify_one(iommu_notifier, &entry); + memory_region_notify_iommu_one(iommu_notifier, &event); } } } |