int acrn_ioreq_init()

in acrn/ioreq.c [601:639]


int acrn_ioreq_init(struct acrn_vm *vm, u64 buf_vma)
{
	struct acrn_ioreq_buffer *set_buffer;
	struct page *page;
	int ret;

	if (vm->ioreq_buf)
		return -EEXIST;

	set_buffer = kzalloc(sizeof(*set_buffer), GFP_KERNEL);
	if (!set_buffer)
		return -ENOMEM;

	ret = pin_user_pages_fast(buf_vma, 1,
				  FOLL_WRITE | FOLL_LONGTERM, &page);
	if (unlikely(ret != 1) || !page) {
		dev_err(acrn_dev.this_device, "Failed to pin ioreq page!\n");
		ret = -EFAULT;
		goto free_buf;
	}

	vm->ioreq_buf = page_address(page);
	vm->ioreq_page = page;
	set_buffer->ioreq_buf = page_to_phys(page);
	ret = hcall_set_ioreq_buffer(vm->vmid, virt_to_phys(set_buffer));
	if (ret < 0) {
		dev_err(acrn_dev.this_device, "Failed to init ioreq buffer!\n");
		unpin_user_page(page);
		vm->ioreq_buf = NULL;
		goto free_buf;
	}

	dev_dbg(acrn_dev.this_device,
		"Init ioreq buffer %pK!\n", vm->ioreq_buf);
	ret = 0;
free_buf:
	kfree(set_buffer);
	return ret;
}