mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-21 14:11:20 +00: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
5 changed files with 20 additions and 3 deletions
|
@ -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_unmap(dev, sgt->sgl->dma_address, size);
|
||||||
__iommu_dma_free_pages(sh->pages, PAGE_ALIGN(size) >> PAGE_SHIFT);
|
__iommu_dma_free_pages(sh->pages, PAGE_ALIGN(size) >> PAGE_SHIFT);
|
||||||
sg_free_table(&sh->sgt);
|
sg_free_table(&sh->sgt);
|
||||||
|
kfree(sh);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_DMA_REMAP */
|
#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)
|
u32 pasid, bool fault_ignore)
|
||||||
{
|
{
|
||||||
struct pasid_entry *pte;
|
struct pasid_entry *pte;
|
||||||
u16 did;
|
u16 did, pgtt;
|
||||||
|
|
||||||
pte = intel_pasid_get_entry(dev, pasid);
|
pte = intel_pasid_get_entry(dev, pasid);
|
||||||
if (WARN_ON(!pte))
|
if (WARN_ON(!pte))
|
||||||
|
@ -521,13 +521,19 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
did = pasid_get_domain_id(pte);
|
did = pasid_get_domain_id(pte);
|
||||||
|
pgtt = pasid_pte_get_pgtt(pte);
|
||||||
|
|
||||||
intel_pasid_clear_entry(dev, pasid, fault_ignore);
|
intel_pasid_clear_entry(dev, pasid, fault_ignore);
|
||||||
|
|
||||||
if (!ecap_coherent(iommu->ecap))
|
if (!ecap_coherent(iommu->ecap))
|
||||||
clflush_cache_range(pte, sizeof(*pte));
|
clflush_cache_range(pte, sizeof(*pte));
|
||||||
|
|
||||||
pasid_cache_invalidation_with_pasid(iommu, did, pasid);
|
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. */
|
/* Device IOTLB doesn't need to be flushed in caching mode. */
|
||||||
if (!cap_caching_mode(iommu->cap))
|
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;
|
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;
|
extern unsigned int intel_pasid_max_id;
|
||||||
int intel_pasid_alloc_table(struct device *dev);
|
int intel_pasid_alloc_table(struct device *dev);
|
||||||
void intel_pasid_free_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);
|
kfree_rcu(sdev, rcu);
|
||||||
|
|
||||||
if (list_empty(&svm->devs)) {
|
if (list_empty(&svm->devs)) {
|
||||||
intel_svm_free_pasid(mm);
|
|
||||||
if (svm->notifier.ops) {
|
if (svm->notifier.ops) {
|
||||||
mmu_notifier_unregister(&svm->notifier, mm);
|
mmu_notifier_unregister(&svm->notifier, mm);
|
||||||
/* Clear mm's pasid. */
|
/* Clear mm's pasid. */
|
||||||
|
@ -690,6 +689,8 @@ static int intel_svm_unbind_mm(struct device *dev, u32 pasid)
|
||||||
kfree(svm);
|
kfree(svm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Drop a PASID reference and free it if no reference. */
|
||||||
|
intel_svm_free_pasid(mm);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -924,6 +924,9 @@ void iommu_group_remove_device(struct device *dev)
|
||||||
struct iommu_group *group = dev->iommu_group;
|
struct iommu_group *group = dev->iommu_group;
|
||||||
struct group_device *tmp_device, *device = NULL;
|
struct group_device *tmp_device, *device = NULL;
|
||||||
|
|
||||||
|
if (!group)
|
||||||
|
return;
|
||||||
|
|
||||||
dev_info(dev, "Removing from iommu group %d\n", group->id);
|
dev_info(dev, "Removing from iommu group %d\n", group->id);
|
||||||
|
|
||||||
/* Pre-notify listeners that a device is being removed. */
|
/* Pre-notify listeners that a device is being removed. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue