From: Yi Liu <yi.l.liu@intel.com>
When either 'Set Root Table Pointer' or 'Translation Enable' bit is changed,
all pasid bindings on host side become stale and need to be updated.
Introduce a helper function vtd_replay_pasid_bindings_all() to go through all
pasid entries in all passthrough devices to update host side bindings.
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
---
hw/i386/intel_iommu.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index d8b4296fe4..0a86bd47b2 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -89,6 +89,7 @@ struct vtd_iotlb_key {
static void vtd_address_space_refresh_all(IntelIOMMUState *s);
static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n);
+static void vtd_replay_pasid_bindings_all(IntelIOMMUState *s);
static void vtd_pasid_cache_reset_locked(IntelIOMMUState *s);
static void vtd_pasid_cache_sync(IntelIOMMUState *s,
@@ -3044,6 +3045,7 @@ static void vtd_handle_gcmd_srtp(IntelIOMMUState *s)
vtd_set_clear_mask_long(s, DMAR_GSTS_REG, 0, VTD_GSTS_RTPS);
vtd_reset_caches(s);
vtd_address_space_refresh_all(s);
+ vtd_replay_pasid_bindings_all(s);
}
/* Set Interrupt Remap Table Pointer */
@@ -3078,6 +3080,7 @@ static void vtd_handle_gcmd_te(IntelIOMMUState *s, bool en)
vtd_reset_caches(s);
vtd_address_space_refresh_all(s);
+ vtd_replay_pasid_bindings_all(s);
}
/* Handle Interrupt Remap Enable/Disable */
@@ -3758,6 +3761,17 @@ static void vtd_replay_guest_pasid_bindings(IntelIOMMUState *s,
}
}
+static void vtd_replay_pasid_bindings_all(IntelIOMMUState *s)
+{
+ VTDPASIDCacheInfo pc_info = { .type = VTD_PASID_CACHE_GLOBAL_INV };
+
+ if (!s->flts || !s->root_scalable || !s->dmar_enabled) {
+ return;
+ }
+
+ vtd_replay_guest_pasid_bindings(s, &pc_info);
+}
+
/* Update the pasid cache in vIOMMU */
static void vtd_pasid_cache_sync(IntelIOMMUState *s, VTDPASIDCacheInfo *pc_info)
{
--
2.47.1