@@ -72,6 +72,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_refresh_pasid_bind(IntelIOMMUState *s);
static void vtd_pasid_cache_reset(IntelIOMMUState *s);
static void vtd_pasid_cache_sync(IntelIOMMUState *s,
@@ -3292,6 +3293,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_refresh_pasid_bind(s);
}
/* Set Interrupt Remap Table Pointer */
@@ -3326,6 +3328,7 @@ static void vtd_handle_gcmd_te(IntelIOMMUState *s, bool en)
vtd_reset_caches(s);
vtd_address_space_refresh_all(s);
+ vtd_refresh_pasid_bind(s);
}
/* Handle Interrupt Remap Enable/Disable */
@@ -3960,6 +3963,28 @@ static void vtd_replay_guest_pasid_bindings(IntelIOMMUState *s,
}
}
+static void vtd_refresh_pasid_bind(IntelIOMMUState *s)
+{
+ VTDPASIDCacheInfo pc_info = { .error_happened = false,
+ .type = VTD_PASID_CACHE_GLOBAL_INV };
+
+ /*
+ * Only when dmar is enabled, should pasid bindings replayed,
+ * otherwise no need to replay.
+ */
+ if (!s->dmar_enabled) {
+ return;
+ }
+
+ if (!s->scalable_modern || !s->root_scalable) {
+ return;
+ }
+
+ vtd_iommu_lock(s);
+ vtd_replay_guest_pasid_bindings(s, &pc_info);
+ vtd_iommu_unlock(s);
+}
+
/*
* This function syncs the pasid bindings between guest and host.
* It includes updating the pasid cache in vIOMMU and updating the
@@ -6051,6 +6076,7 @@ static void vtd_reset(DeviceState *dev)
vtd_init(s);
vtd_address_space_refresh_all(s);
+ vtd_refresh_pasid_bind(s);
}
static AddressSpace *vtd_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)