in dfl-afu-dma-region.c [34:72]
static int afu_dma_pin_pages(struct dfl_feature_platform_data *pdata,
struct dfl_afu_dma_region *region)
{
int npages = region->length >> PAGE_SHIFT;
struct device *dev = &pdata->dev->dev;
int ret, pinned;
ret = account_locked_vm(current->mm, npages, true);
if (ret)
return ret;
region->pages = kcalloc(npages, sizeof(struct page *), GFP_KERNEL);
if (!region->pages) {
ret = -ENOMEM;
goto unlock_vm;
}
pinned = pin_user_pages_fast(region->user_addr, npages, FOLL_WRITE,
region->pages);
if (pinned < 0) {
ret = pinned;
goto free_pages;
} else if (pinned != npages) {
ret = -EFAULT;
goto unpin_pages;
}
dev_dbg(dev, "%d pages pinned\n", pinned);
return 0;
unpin_pages:
unpin_user_pages(region->pages, pinned);
free_pages:
kfree(region->pages);
unlock_vm:
account_locked_vm(current->mm, npages, false);
return ret;
}