@@ -1196,14 +1196,33 @@ static uint64_t vtd_context_cache_invalidate(IntelIOMMUState *s, uint64_t val)
static void vtd_iotlb_global_invalidate(IntelIOMMUState *s)
{
+ IntelIOMMUNotifierNode *node;
+
trace_vtd_iotlb_reset("global invalidation recved");
vtd_reset_iotlb(s);
+
+ QLIST_FOREACH(node, &s->notifiers_list, next) {
+ memory_region_iommu_replay_all(&node->vtd_as->iommu);
+ }
}
static void vtd_iotlb_domain_invalidate(IntelIOMMUState *s, uint16_t domain_id)
{
+ IntelIOMMUNotifierNode *node;
+ VTDContextEntry ce;
+ VTDAddressSpace *vtd_as;
+
g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_domain,
&domain_id);
+
+ QLIST_FOREACH(node, &s->notifiers_list, next) {
+ vtd_as = node->vtd_as;
+ if (!vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
+ vtd_as->devfn, &ce) &&
+ domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) {
+ memory_region_iommu_replay_all(&vtd_as->iommu);
+ }
+ }
}
static int vtd_page_invalidate_notify_hook(IOMMUTLBEntry *entry,
We were capturing context entry invalidations to trap IOMMU mapping changes. This patch listens to domain/global invalidation requests too. We need this for the sake that guest operating system might send one domain/global invalidation instead of several PSIs in some cases. To better survive with that, we'd better replay corresponding regions as well for these invalidations, even if this will turn the performance down a bit. An example in Linux (4.10.0) Intel IOMMU driver: /* * Fallback to domain selective flush if no PSI support or the size is * too big. * PSI requires page size to be 2 ^ x, and the base address is naturally * aligned to the size */ if (!cap_pgsel_inv(iommu->cap) || mask > cap_max_amask_val(iommu->cap)) iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH); else iommu->flush.flush_iotlb(iommu, did, addr | ih, mask, DMA_TLB_PSI_FLUSH); If we don't have this, when above DSI FLUSH happens, we might have unaligned mapping. Signed-off-by: Peter Xu <peterx@redhat.com> --- hw/i386/intel_iommu.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)