[PATCH v6 10/25] iommufd/viommu: Add IOMMUFD_CMD_HW_QUEUE_ALLOC ioctl

Nicolin Chen nicolinc at nvidia.com
Wed Jun 25 16:06:27 PDT 2025


On Wed, Jun 25, 2025 at 03:45:08AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen <nicolinc at nvidia.com>
> > Sent: Saturday, June 14, 2025 3:15 PM
> > +
> > +	offset =
> > +		cmd->nesting_parent_iova - PAGE_ALIGN(cmd-
> > >nesting_parent_iova);
> > +	max_npages = DIV_ROUND_UP(offset + cmd->length, PAGE_SIZE);
> > +
> > +	/*
> > +	 * FIXME allocation may fail when sizeof(*pages) * max_npages is
> > +	 * larger than PAGE_SIZE. This might need a new API returning a
> > +	 * bio_vec or something more efficient.
> > +	 */
> > +	pages = kcalloc(max_npages, sizeof(*pages), GFP_KERNEL);
> > +	if (!pages)
> > +		return ERR_PTR(-ENOMEM);
> > +
> 
> any allocation may fail... can you elaborate more here? How does
> PAGE_SIZE become a boundary?

Memory fragmentation can be the reason. It's easy to get one page
but not for contiguous pages.

Jason suggested to use kvcalloc, so I am adding this:
@@ -249,11 +249,10 @@ iommufd_hw_queue_alloc_phys(struct iommu_hw_queue_alloc *cmd,
        max_npages = DIV_ROUND_UP(offset + cmd->length, PAGE_SIZE);

        /*
-        * FIXME allocation may fail when sizeof(*pages) * max_npages is
-        * larger than PAGE_SIZE. This might need a new API returning a
-        * bio_vec or something more efficient.
+        * Use kvcalloc() to avoid memory fragmentation for a large page array.
+        * Set __GFP_NOWARN to avoid syzkaller blowups
         */
-       pages = kcalloc(max_npages, sizeof(*pages), GFP_KERNEL);
+       pages = kvcalloc(max_npages, sizeof(*pages), GFP_KERNEL | __GFP_NOWARN);
        if (!pages)
                return ERR_PTR(-ENOMEM);

Thanks
Nicolin



More information about the linux-arm-kernel mailing list