mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
iommu/vt-d: Fix copied_tables bitmap leak on error in copy_translation_tables
The iommu->copied_tables bitmap was introduced by the IOMMU live
update series to track which context entries have been copied from
the previous kernel. The allocation via bitmap_zalloc() was added
inside copy_translation_tables(), but the error paths were not
updated to free it:
1. When old_rt_phys is 0 (invalid root table address)
2. When memremap(old_rt_phys) fails
3. When kcalloc for ctxt_tbls fails (goto out_unmap, which only
unmaps old_rt without releasing the bitmap)
The bitmap is only cleaned up by free_dmar_iommu(), which is
called from the free_iommu error label in init_dmars(). However,
when copy_translation_tables() fails, init_dmars() does not jump
to free_iommu -- it logs the error, falls through, and continues
with the next IOMMU. As a result, copied_tables is leaked.
Fix this by converting the two early returns to goto a new
err_free_bitmap label, and by making out_unmap fall through to
it so that the bitmap is always freed on any error path. The
success path performs memunmap(old_rt) inline and returns 0
directly, since copied_tables must remain allocated for
subsequent use.
Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
parent
5b3ba0a002
commit
d9ef887fb2
|
|
@ -1557,12 +1557,16 @@ static int copy_translation_tables(struct intel_iommu *iommu)
|
|||
return -ENOMEM;
|
||||
|
||||
old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
|
||||
if (!old_rt_phys)
|
||||
return -EINVAL;
|
||||
if (!old_rt_phys) {
|
||||
ret = -EINVAL;
|
||||
goto err_free_bitmap;
|
||||
}
|
||||
|
||||
old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
|
||||
if (!old_rt)
|
||||
return -ENOMEM;
|
||||
if (!old_rt) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_bitmap;
|
||||
}
|
||||
|
||||
/* This is too big for the stack - allocate it from slab */
|
||||
ctxt_table_entries = ext ? 512 : 256;
|
||||
|
|
@ -1606,11 +1610,14 @@ static int copy_translation_tables(struct intel_iommu *iommu)
|
|||
|
||||
__iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
|
||||
|
||||
ret = 0;
|
||||
memunmap(old_rt);
|
||||
return 0;
|
||||
|
||||
out_unmap:
|
||||
memunmap(old_rt);
|
||||
|
||||
err_free_bitmap:
|
||||
bitmap_free(iommu->copied_tables);
|
||||
iommu->copied_tables = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user