in vboxguest/vboxguest_core.c [269:312]
static int vbg_balloon_inflate(struct vbg_dev *gdev, u32 chunk_idx)
{
struct vmmdev_memballoon_change *req = gdev->mem_balloon.change_req;
struct page **pages;
int i, rc, ret;
pages = kmalloc_array(VMMDEV_MEMORY_BALLOON_CHUNK_PAGES,
sizeof(*pages),
GFP_KERNEL | __GFP_NOWARN);
if (!pages)
return -ENOMEM;
req->header.size = sizeof(*req);
req->inflate = true;
req->pages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES;
for (i = 0; i < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; i++) {
pages[i] = alloc_page(GFP_KERNEL | __GFP_NOWARN);
if (!pages[i]) {
ret = -ENOMEM;
goto out_error;
}
req->phys_page[i] = page_to_phys(pages[i]);
}
rc = vbg_req_perform(gdev, req);
if (rc < 0) {
vbg_err("%s error, rc: %d\n", __func__, rc);
ret = vbg_status_code_to_errno(rc);
goto out_error;
}
gdev->mem_balloon.pages[chunk_idx] = pages;
return 0;
out_error:
while (--i >= 0)
__free_page(pages[i]);
kfree(pages);
return ret;
}