Skip to content

Commit 5e2ff24

Browse files
jgunthorpejoergroedel
authored andcommitted
iommu: Clear the freelist after iommu_put_pages_list()
The commit below reworked how iommu_put_pages_list() worked to not do list_del() on every entry. This was done expecting all the callers to already re-init the list so doing a per-item deletion is not efficient. It was missed that fq_ring_free_locked() re-uses its list after calling iommu_put_pages_list() and so the leftover list reaches free'd struct pages and will crash or WARN/BUG/etc. Reinit the list to empty in fq_ring_free_locked() after calling iommu_put_pages_list(). Audit to see if any other callers of iommu_put_pages_list() need the list to be empty: - iommu_dma_free_fq_single() and iommu_dma_free_fq_percpu() immediately frees the memory - iommu_v1_map_pages(), v1_free_pgtable(), domain_exit(), riscv_iommu_map_pages() uses a stack variable which goes out of scope - intel_iommu_tlb_sync() uses a gather in a iotlb_sync() callback, the caller re-inits the gather Fixes: 13f43d7 ("iommu/pages: Formalize the freelist API") Reported-by: Borah, Chaitanya Kumar <chaitanya.kumar.borah@intel.com> Closes: https://lore.kernel.org/r/SJ1PR11MB61292CE72D7BE06B8810021CB997A@SJ1PR11MB6129.namprd11.prod.outlook.com Tested-by: Borah, Chaitanya Kumar <chaitanya.kumar.borah@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Link: https://lore.kernel.org/r/0-v1-7d4dfa6140f7+11f04-iommu_freelist_init_jgg@nvidia.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent e436576 commit 5e2ff24

File tree

2 files changed

+5
-1
lines changed

2 files changed

+5
-1
lines changed

drivers/iommu/dma-iommu.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ static void fq_ring_free_locked(struct iommu_dma_cookie *cookie, struct iova_fq
154154
fq->entries[idx].iova_pfn,
155155
fq->entries[idx].pages);
156156

157+
fq->entries[idx].freelist =
158+
IOMMU_PAGES_LIST_INIT(fq->entries[idx].freelist);
157159
fq->head = (fq->head + 1) & fq->mod_mask;
158160
}
159161
}

drivers/iommu/iommu-pages.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ EXPORT_SYMBOL_GPL(iommu_free_pages);
105105
* iommu_put_pages_list - free a list of pages.
106106
* @list: The list of pages to be freed
107107
*
108-
* Frees a list of pages allocated by iommu_alloc_pages_node_sz().
108+
* Frees a list of pages allocated by iommu_alloc_pages_node_sz(). On return the
109+
* passed list is invalid, the caller must use IOMMU_PAGES_LIST_INIT to reinit
110+
* the list if it expects to use it again.
109111
*/
110112
void iommu_put_pages_list(struct iommu_pages_list *list)
111113
{

0 commit comments

Comments
 (0)