memory: Add IOMMUTLBEvent

This way we can tell between regular IOMMUTLBEntry (entry of IOMMU
hardware) and notifications.

In the notifications, we set explicitly if it is a MAPs or an UNMAP,
instead of trusting in entry permissions to differentiate them.

Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20201116165506.31315-3-eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Eugenio Pérez 2020-11-16 17:55:03 +01:00 committed by Michael S. Tsirkin
parent 3b5ebf8532
commit 5039caf3c4
9 changed files with 143 additions and 122 deletions

View file

@ -1943,11 +1943,15 @@ void memory_region_unregister_iommu_notifier(MemoryRegion *mr,
}
void memory_region_notify_iommu_one(IOMMUNotifier *notifier,
IOMMUTLBEntry *entry)
IOMMUTLBEvent *event)
{
IOMMUNotifierFlag request_flags;
IOMMUTLBEntry *entry = &event->entry;
hwaddr entry_end = entry->iova + entry->addr_mask;
if (event->type == IOMMU_NOTIFIER_UNMAP) {
assert(entry->perm == IOMMU_NONE);
}
/*
* Skip the notification if the notification does not overlap
* with registered range.
@ -1958,20 +1962,14 @@ void memory_region_notify_iommu_one(IOMMUNotifier *notifier,
assert(entry->iova >= notifier->start && entry_end <= notifier->end);
if (entry->perm & IOMMU_RW) {
request_flags = IOMMU_NOTIFIER_MAP;
} else {
request_flags = IOMMU_NOTIFIER_UNMAP;
}
if (notifier->notifier_flags & request_flags) {
if (event->type & notifier->notifier_flags) {
notifier->notify(notifier, entry);
}
}
void memory_region_notify_iommu(IOMMUMemoryRegion *iommu_mr,
int iommu_idx,
IOMMUTLBEntry entry)
IOMMUTLBEvent event)
{
IOMMUNotifier *iommu_notifier;
@ -1979,7 +1977,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_iommu_one(iommu_notifier, &entry);
memory_region_notify_iommu_one(iommu_notifier, &event);
}
}
}