mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-01 16:14:13 +08:00
IOMMU Fixes for Linux v5.14-rc6
Including: - Fix for a potential NULL-ptr dereference in IOMMU core code - Two resource leak fixes - Cache flush fix in the Intel VT-d driver -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEr9jSbILcajRFYWYyK/BELZcBGuMFAmEfXloACgkQK/BELZcB GuNC5w/6A4RRldvl5oKsHY7Nf49XY1Ydh9mgILqZY7bYE+8LaOmgPi9osQ5en+ze dg46EgEBr02UHBN561FcemhgUjoT21FcG0uVEUfODLjjB46s4/tzIno+NwEFNjsT MZfosGnKu4QFGS7P+kAuIOxoNRT7aHqvtB/vR4nfma3KcjUTUCyPRkXTs48307a9 1/fAaTaUnQ1fu61M4r5HsCpzs9KdiNX91NabvwbzYB479p69FM1mYSFxHc0nHzOR e0fpf8W/+0FgzjYMeVmrgRRGVrODNpL6tRPbFIETkjWtX4ESH5yb5qdtooLWQlQq uktARsuXqbO7b5vARHs3BbUVAkvMwniVoxDrpzMSmWbkO8EX1VJrHoHMIqvv0jMC Q6DOroc465Ou3wFRaPmuK2VT0Wc8QQOu+qJHcLML3GwD+cetBCQzH89sPD1kKPOb LskGecRP7k/LvGCbpU4Zk6aZZ5eGGrXKve1T7k4OQW+HfLeeKGjTNpj3+n+VE1Pd /ATX/Iq++SIMJ+oBEpMHxTjyL7VZrJkdJFodTJw69ktdVh2bm5Y041fqi4PxNO6J Ez0oIhrgWscfeSEE1jrvPbojTCwT82gEg5m/lLX6Rj3YWpwMa9WykfJEhHqQks/2 2uXLhAwVJxNCpEYg6f8iiFxMIp9kQPAkmQGMpgKnSDFG2j4PoNQ= =Jnt4 -----END PGP SIGNATURE----- Merge tag 'iommu-fixes-v5.14-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu Pull iommu fixes from Joerg Roedel: - Fix for a potential NULL-ptr dereference in IOMMU core code - Two resource leak fixes - Cache flush fix in the Intel VT-d driver * tag 'iommu-fixes-v5.14-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/vt-d: Fix incomplete cache flush in intel_pasid_tear_down_entry() iommu/vt-d: Fix PASID reference leak iommu: Check if group is NULL before remove device iommu/dma: Fix leak in non-contiguous API
This commit is contained in:
commit
b7d184d37e
@ -768,6 +768,7 @@ static void iommu_dma_free_noncontiguous(struct device *dev, size_t size,
|
||||
__iommu_dma_unmap(dev, sgt->sgl->dma_address, size);
|
||||
__iommu_dma_free_pages(sh->pages, PAGE_ALIGN(size) >> PAGE_SHIFT);
|
||||
sg_free_table(&sh->sgt);
|
||||
kfree(sh);
|
||||
}
|
||||
#endif /* CONFIG_DMA_REMAP */
|
||||
|
||||
|
@ -511,7 +511,7 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev,
|
||||
u32 pasid, bool fault_ignore)
|
||||
{
|
||||
struct pasid_entry *pte;
|
||||
u16 did;
|
||||
u16 did, pgtt;
|
||||
|
||||
pte = intel_pasid_get_entry(dev, pasid);
|
||||
if (WARN_ON(!pte))
|
||||
@ -521,13 +521,19 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev,
|
||||
return;
|
||||
|
||||
did = pasid_get_domain_id(pte);
|
||||
pgtt = pasid_pte_get_pgtt(pte);
|
||||
|
||||
intel_pasid_clear_entry(dev, pasid, fault_ignore);
|
||||
|
||||
if (!ecap_coherent(iommu->ecap))
|
||||
clflush_cache_range(pte, sizeof(*pte));
|
||||
|
||||
pasid_cache_invalidation_with_pasid(iommu, did, pasid);
|
||||
qi_flush_piotlb(iommu, did, pasid, 0, -1, 0);
|
||||
|
||||
if (pgtt == PASID_ENTRY_PGTT_PT || pgtt == PASID_ENTRY_PGTT_FL_ONLY)
|
||||
qi_flush_piotlb(iommu, did, pasid, 0, -1, 0);
|
||||
else
|
||||
iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
|
||||
|
||||
/* Device IOTLB doesn't need to be flushed in caching mode. */
|
||||
if (!cap_caching_mode(iommu->cap))
|
||||
|
@ -99,6 +99,12 @@ static inline bool pasid_pte_is_present(struct pasid_entry *pte)
|
||||
return READ_ONCE(pte->val[0]) & PASID_PTE_PRESENT;
|
||||
}
|
||||
|
||||
/* Get PGTT field of a PASID table entry */
|
||||
static inline u16 pasid_pte_get_pgtt(struct pasid_entry *pte)
|
||||
{
|
||||
return (u16)((READ_ONCE(pte->val[0]) >> 6) & 0x7);
|
||||
}
|
||||
|
||||
extern unsigned int intel_pasid_max_id;
|
||||
int intel_pasid_alloc_table(struct device *dev);
|
||||
void intel_pasid_free_table(struct device *dev);
|
||||
|
@ -675,7 +675,6 @@ static int intel_svm_unbind_mm(struct device *dev, u32 pasid)
|
||||
kfree_rcu(sdev, rcu);
|
||||
|
||||
if (list_empty(&svm->devs)) {
|
||||
intel_svm_free_pasid(mm);
|
||||
if (svm->notifier.ops) {
|
||||
mmu_notifier_unregister(&svm->notifier, mm);
|
||||
/* Clear mm's pasid. */
|
||||
@ -690,6 +689,8 @@ static int intel_svm_unbind_mm(struct device *dev, u32 pasid)
|
||||
kfree(svm);
|
||||
}
|
||||
}
|
||||
/* Drop a PASID reference and free it if no reference. */
|
||||
intel_svm_free_pasid(mm);
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
|
@ -924,6 +924,9 @@ void iommu_group_remove_device(struct device *dev)
|
||||
struct iommu_group *group = dev->iommu_group;
|
||||
struct group_device *tmp_device, *device = NULL;
|
||||
|
||||
if (!group)
|
||||
return;
|
||||
|
||||
dev_info(dev, "Removing from iommu group %d\n", group->id);
|
||||
|
||||
/* Pre-notify listeners that a device is being removed. */
|
||||
|
Loading…
Reference in New Issue
Block a user