From: Zhenzhong Duan <[email protected]> For VTD_INV_DESC_PASIDC_G_PASID_SI typed pc_inv_dsc invalidation, if an pasid entry is just removed, it can never be a new entry to add. So calling vtd_replay_pasid_bind_for_dev() is unnecessary.
Introduce a new field accel_pce_deleted in VTDPASIDCacheInfo to mark this case and to do the bypassing. Suggested-by: Yi Liu <[email protected]> Signed-off-by: Zhenzhong Duan <[email protected]> Reviewed-by: Yi Liu <[email protected]> Tested-by: Xudong Hao <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Message-Id: <[email protected]> --- hw/i386/intel_iommu_accel.c | 16 +++++++++++++--- hw/i386/intel_iommu_internal.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/hw/i386/intel_iommu_accel.c b/hw/i386/intel_iommu_accel.c index ed0d6bda7e..b823c405a1 100644 --- a/hw/i386/intel_iommu_accel.c +++ b/hw/i386/intel_iommu_accel.c @@ -280,10 +280,15 @@ static void vtd_accel_fill_pc(VTDHostIOMMUDevice *vtd_hiod, uint32_t pasid, QLIST_INSERT_HEAD(&vtd_hiod->pasid_cache_list, vtd_pce, next); } -static void vtd_accel_delete_pc(VTDAccelPASIDCacheEntry *vtd_pce) +static void vtd_accel_delete_pc(VTDAccelPASIDCacheEntry *vtd_pce, + VTDPASIDCacheInfo *pc_info) { QLIST_REMOVE(vtd_pce, next); g_free(vtd_pce); + + if (pc_info->type == VTD_INV_DESC_PASIDC_G_PASID_SI) { + pc_info->accel_pce_deleted = true; + } } static void @@ -319,7 +324,7 @@ vtd_accel_pasid_cache_invalidate_one(VTDAccelPASIDCacheEntry *vtd_pce, * to be either all-zero or non-present. Either case means existing * pasid cache should be invalidated. */ - vtd_accel_delete_pc(vtd_pce); + vtd_accel_delete_pc(vtd_pce, pc_info); } } @@ -472,7 +477,12 @@ void vtd_accel_pasid_cache_sync(IntelIOMMUState *s, VTDPASIDCacheInfo *pc_info) * removals before additions to optimize the replay process. */ vtd_accel_pasid_cache_invalidate(vtd_hiod, pc_info); - vtd_accel_replay_pasid_bind_for_dev(vtd_hiod, start, end, pc_info); + + if (pc_info->accel_pce_deleted) { + pc_info->accel_pce_deleted = false; + } else { + vtd_accel_replay_pasid_bind_for_dev(vtd_hiod, start, end, pc_info); + } } } diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 9307825017..64a38afa85 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -630,6 +630,7 @@ typedef struct VTDPASIDCacheInfo { uint8_t type; uint16_t did; uint32_t pasid; + bool accel_pce_deleted; } VTDPASIDCacheInfo; typedef struct VTDPIOTLBInvInfo { -- MST
