From 37c743761d20c16891856c5bef2e7b3fb89893b6 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Mon, 5 Dec 2022 18:11:36 -0500 Subject: [PATCH] intel-iommu: Send unmap notifications for domain or global inv desc Content-type: text/plain Signed-off-by: Peter Xu --- hw/i386/intel_iommu.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index a08ee85edf..2c6ca68df0 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -206,6 +206,23 @@ static inline gboolean vtd_as_has_map_notifier(VTDAddressSpace *as) return as->notifier_flags & IOMMU_NOTIFIER_MAP; } +static void vtd_as_notify_unmap(VTDAddressSpace *as, hwaddr iova, + hwaddr addr_mask) +{ + IOMMUTLBEvent event = { + .type = IOMMU_NOTIFIER_UNMAP, + .entry = { + .target_as = &address_space_memory, + .iova = iova, + .translated_addr = 0, + .addr_mask = addr_mask, + .perm = IOMMU_NONE, + }, + }; + + memory_region_notify_iommu(&as->iommu, 0, event); +} + /* GHashTable functions */ static gboolean vtd_iotlb_equal(gconstpointer v1, gconstpointer v2) { @@ -1530,13 +1547,15 @@ static int vtd_sync_shadow_page_table_range(VTDAddressSpace *vtd_as, return vtd_page_walk(s, ce, addr, addr + size, &info, vtd_as->pasid); } -static int vtd_sync_shadow_page_table(VTDAddressSpace *vtd_as) +static int vtd_address_space_sync(VTDAddressSpace *vtd_as) { int ret; VTDContextEntry ce; IOMMUNotifier *n; - if (!(vtd_as->iommu.iommu_notify_flags & IOMMU_NOTIFIER_IOTLB_EVENTS)) { + /* If no MAP notifier registered, we simply invalidate all the cache */ + if (!vtd_as_has_map_notifier(vtd_as)) { + vtd_as_notify_unmap(vtd_as, 0, HWADDR_MAX); return 0; } @@ -2000,7 +2019,7 @@ static void vtd_iommu_replay_all(IntelIOMMUState *s) VTDAddressSpace *vtd_as; QLIST_FOREACH(vtd_as, &s->vtd_as_with_notifiers, next) { - vtd_sync_shadow_page_table(vtd_as); + vtd_address_space_sync(vtd_as); } } @@ -2082,7 +2101,7 @@ static void vtd_context_device_invalidate(IntelIOMMUState *s, * framework will skip MAP notifications if that * happened. */ - vtd_sync_shadow_page_table(vtd_as); + vtd_address_space_sync(vtd_as); } } } @@ -2140,7 +2159,7 @@ static void vtd_iotlb_domain_invalidate(IntelIOMMUState *s, uint16_t domain_id) if (!vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus), vtd_as->devfn, &ce) && domain_id == vtd_get_domain_id(s, &ce, vtd_as->pasid)) { - vtd_sync_shadow_page_table(vtd_as); + vtd_address_space_sync(vtd_as); } } } @@ -2174,17 +2193,7 @@ static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s, * page tables. We just deliver the PSI down to * invalidate caches. */ - IOMMUTLBEvent event = { - .type = IOMMU_NOTIFIER_UNMAP, - .entry = { - .target_as = &address_space_memory, - .iova = addr, - .translated_addr = 0, - .addr_mask = size - 1, - .perm = IOMMU_NONE, - }, - }; - memory_region_notify_iommu(&vtd_as->iommu, 0, event); + vtd_as_notify_unmap(vtd_as, addr, size - 1); } } } -- 2.37.3