int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab,
                                  struct virtio_gpu_ctrl_command *cmd,
                                  uint64_t **addr, struct iovec **iov)
{
    struct virtio_gpu_mem_entry *ents;
    size_t esize, s;
    int i;

    if (ab->nr_entries > 16384) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: nr_entries is too big (%d > 16384)\n",
                      __func__, ab->nr_entries);
        return -1;
    }

    esize = sizeof(*ents) * ab->nr_entries;
    ents = g_malloc(esize);
    s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
                   sizeof(*ab), ents, esize);
    if (s != esize) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: command data size incorrect %zu vs %zu\n",
                      __func__, s, esize);
        g_free(ents);
        return -1;
    }

    *iov = g_malloc0(sizeof(struct iovec) * ab->nr_entries);
    if (addr) {
        *addr = g_malloc0(sizeof(uint64_t) * ab->nr_entries);
    }
    for (i = 0; i < ab->nr_entries; i++) {
        hwaddr len = ents[i].length;
        (*iov)[i].iov_len = ents[i].length;
        (*iov)[i].iov_base = cpu_physical_memory_map(ents[i].addr, &len, 1);
        if (addr) {
            (*addr)[i] = ents[i].addr;
        }
        if (!(*iov)[i].iov_base || len != ents[i].length) {
            qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for"
                          " resource %d element %d\n",
                          __func__, ab->resource_id, i);
            virtio_gpu_cleanup_mapping_iov(*iov, i);
            g_free(ents);
            *iov = NULL;
            if (addr) {
                g_free(*addr);
                *addr = NULL;
            }
            return -1;
        }
    }
    g_free(ents);
    return 0;
}

The product does not release a resource after its effective lifetime has ended, i.e., after the resource is no longer needed.