mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
iommufd: Add iopt_area_alloc()
We never initialize the two interval tree nodes, and zero fill is not the
same as RB_CLEAR_NODE. This can hide issues where we missed adding the
area to the trees. Factor out the allocation and clear the two nodes.
Fixes: 51fe6141f0
("iommufd: Data structure to provide IOVA to PFN mapping")
Link: https://lore.kernel.org/r/20231030145035.GG691768@ziepe.ca
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
e7250ab7ca
commit
361d744ddd
@ -222,6 +222,18 @@ static int iopt_insert_area(struct io_pagetable *iopt, struct iopt_area *area,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct iopt_area *iopt_area_alloc(void)
|
||||
{
|
||||
struct iopt_area *area;
|
||||
|
||||
area = kzalloc(sizeof(*area), GFP_KERNEL_ACCOUNT);
|
||||
if (!area)
|
||||
return NULL;
|
||||
RB_CLEAR_NODE(&area->node.rb);
|
||||
RB_CLEAR_NODE(&area->pages_node.rb);
|
||||
return area;
|
||||
}
|
||||
|
||||
static int iopt_alloc_area_pages(struct io_pagetable *iopt,
|
||||
struct list_head *pages_list,
|
||||
unsigned long length, unsigned long *dst_iova,
|
||||
@ -232,7 +244,7 @@ static int iopt_alloc_area_pages(struct io_pagetable *iopt,
|
||||
int rc = 0;
|
||||
|
||||
list_for_each_entry(elm, pages_list, next) {
|
||||
elm->area = kzalloc(sizeof(*elm->area), GFP_KERNEL_ACCOUNT);
|
||||
elm->area = iopt_area_alloc();
|
||||
if (!elm->area)
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -1177,11 +1189,11 @@ static int iopt_area_split(struct iopt_area *area, unsigned long iova)
|
||||
iopt_area_start_byte(area, new_start) & (alignment - 1))
|
||||
return -EINVAL;
|
||||
|
||||
lhs = kzalloc(sizeof(*area), GFP_KERNEL_ACCOUNT);
|
||||
lhs = iopt_area_alloc();
|
||||
if (!lhs)
|
||||
return -ENOMEM;
|
||||
|
||||
rhs = kzalloc(sizeof(*area), GFP_KERNEL_ACCOUNT);
|
||||
rhs = iopt_area_alloc();
|
||||
if (!rhs) {
|
||||
rc = -ENOMEM;
|
||||
goto err_free_lhs;
|
||||
|
@ -1507,6 +1507,8 @@ void iopt_area_unfill_domains(struct iopt_area *area, struct iopt_pages *pages)
|
||||
area, domain, iopt_area_index(area),
|
||||
iopt_area_last_index(area));
|
||||
|
||||
if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
|
||||
WARN_ON(RB_EMPTY_NODE(&area->pages_node.rb));
|
||||
interval_tree_remove(&area->pages_node, &pages->domains_itree);
|
||||
iopt_area_unfill_domain(area, pages, area->storage_domain);
|
||||
area->storage_domain = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user