When system level reset, DMA translation is turned off, all PASID entries become stale and should be deleted.
vtd_hiod list is never accessed without BQL, so no need to guard with iommu lock. Signed-off-by: Zhenzhong Duan <[email protected]> --- hw/i386/intel_iommu_accel.h | 5 +++++ hw/i386/intel_iommu.c | 2 ++ hw/i386/intel_iommu_accel.c | 13 +++++++++++++ 3 files changed, 20 insertions(+) diff --git a/hw/i386/intel_iommu_accel.h b/hw/i386/intel_iommu_accel.h index a77fd06fe0..914c690c26 100644 --- a/hw/i386/intel_iommu_accel.h +++ b/hw/i386/intel_iommu_accel.h @@ -28,6 +28,7 @@ void vtd_flush_host_piotlb_all_locked(IntelIOMMUState *s, uint16_t domain_id, uint32_t pasid, hwaddr addr, uint64_t npages, bool ih); void vtd_pasid_cache_sync_accel(IntelIOMMUState *s, VTDPASIDCacheInfo *pc_info); +void vtd_pasid_cache_reset_accel(IntelIOMMUState *s); void vtd_iommu_ops_update_accel(PCIIOMMUOps *ops); #else static inline bool vtd_check_hiod_accel(IntelIOMMUState *s, @@ -62,6 +63,10 @@ static inline void vtd_pasid_cache_sync_accel(IntelIOMMUState *s, { } +static inline void vtd_pasid_cache_reset_accel(IntelIOMMUState *s) +{ +} + static inline void vtd_iommu_ops_update_accel(PCIIOMMUOps *ops) { } diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 50569460ab..1d0f0bf68b 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -391,6 +391,8 @@ static void vtd_reset_caches(IntelIOMMUState *s) vtd_reset_context_cache_locked(s); vtd_pasid_cache_reset_locked(s); vtd_iommu_unlock(s); + + vtd_pasid_cache_reset_accel(s); } static uint64_t vtd_get_iotlb_gfn(hwaddr addr, uint32_t level) diff --git a/hw/i386/intel_iommu_accel.c b/hw/i386/intel_iommu_accel.c index 2c17365a27..1d7dae87ec 100644 --- a/hw/i386/intel_iommu_accel.c +++ b/hw/i386/intel_iommu_accel.c @@ -493,6 +493,19 @@ void vtd_pasid_cache_sync_accel(IntelIOMMUState *s, VTDPASIDCacheInfo *pc_info) } } +/* Fake a gloal pasid cache invalidation to remove all pasid cache entries */ +void vtd_pasid_cache_reset_accel(IntelIOMMUState *s) +{ + VTDPASIDCacheInfo pc_info = { .type = VTD_INV_DESC_PASIDC_G_GLOBAL }; + VTDHostIOMMUDevice *vtd_hiod; + GHashTableIter as_it; + + g_hash_table_iter_init(&as_it, s->vtd_host_iommu_dev); + while (g_hash_table_iter_next(&as_it, NULL, (void **)&vtd_hiod)) { + vtd_pasid_cache_invalidate(vtd_hiod, &pc_info); + } +} + static uint64_t vtd_get_host_iommu_quirks(uint32_t type, void *caps, uint32_t size) { -- 2.47.3
