Exemplo n.º 1
0
static void kvm_openpic_realize(DeviceState *dev, Error **errp)
{
    SysBusDevice *d = SYS_BUS_DEVICE(dev);
    KVMOpenPICState *opp = KVM_OPENPIC(dev);
    KVMState *s = kvm_state;
    int kvm_openpic_model;
    struct kvm_create_device cd = {0};
    int ret, i;

    if (!kvm_check_extension(s, KVM_CAP_DEVICE_CTRL)) {
        error_setg(errp, "Kernel is lacking Device Control API");
        return;
    }

    switch (opp->model) {
    case OPENPIC_MODEL_FSL_MPIC_20:
        kvm_openpic_model = KVM_DEV_TYPE_FSL_MPIC_20;
        break;

    case OPENPIC_MODEL_FSL_MPIC_42:
        kvm_openpic_model = KVM_DEV_TYPE_FSL_MPIC_42;
        break;

    default:
        error_setg(errp, "Unsupported OpenPIC model %" PRIu32, opp->model);
        return;
    }

    cd.type = kvm_openpic_model;
    ret = kvm_vm_ioctl(s, KVM_CREATE_DEVICE, &cd);
    if (ret < 0) {
        error_setg(errp, "Can't create device %d: %s",
                   cd.type, strerror(errno));
        return;
    }
    opp->fd = cd.fd;

    sysbus_init_mmio(d, &opp->mem);
    qdev_init_gpio_in(dev, kvm_openpic_set_irq, OPENPIC_MAX_IRQ);

    opp->mem_listener.region_add = kvm_openpic_region_add;
    opp->mem_listener.region_del = kvm_openpic_region_del;
    memory_listener_register(&opp->mem_listener, &address_space_memory);

    /* indicate pic capabilities */
    msi_nonbroken = true;
    kvm_kernel_irqchip = true;
    kvm_async_interrupts_allowed = true;

    /* set up irq routing */
    kvm_init_irq_routing(kvm_state);
    for (i = 0; i < 256; ++i) {
        kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
    }

    kvm_msi_via_irqfd_allowed = true;
    kvm_gsi_routing_allowed = true;

    kvm_irqchip_commit_routes(s);
}
Exemplo n.º 2
0
void hostmem_init(HostMem *hostmem)
{
    memset(hostmem, 0, sizeof(*hostmem));

    qemu_mutex_init(&hostmem->current_regions_lock);

    hostmem->listener = (MemoryListener){
        .begin = hostmem_listener_dummy,
        .commit = hostmem_listener_commit,
        .region_add = hostmem_listener_append_region,
        .region_del = hostmem_listener_section_dummy,
        .region_nop = hostmem_listener_append_region,
        .log_start = hostmem_listener_section_dummy,
        .log_stop = hostmem_listener_section_dummy,
        .log_sync = hostmem_listener_section_dummy,
        .log_global_start = hostmem_listener_dummy,
        .log_global_stop = hostmem_listener_dummy,
        .eventfd_add = hostmem_listener_eventfd_dummy,
        .eventfd_del = hostmem_listener_eventfd_dummy,
        .coalesced_mmio_add = hostmem_listener_coalesced_mmio_dummy,
        .coalesced_mmio_del = hostmem_listener_coalesced_mmio_dummy,
        .priority = 10,
    };

    memory_listener_register(&hostmem->listener, &address_space_memory);
    if (hostmem->num_new_regions > 0) {
        hostmem_listener_commit(&hostmem->listener);
    }
}

void hostmem_finalize(HostMem *hostmem)
{
    memory_listener_unregister(&hostmem->listener);
    g_free(hostmem->new_regions);
    g_free(hostmem->current_regions);
    qemu_mutex_destroy(&hostmem->current_regions_lock);
}
Exemplo n.º 3
0
static void whpx_memory_init(void)
{
    memory_listener_register(&whpx_memory_listener, &address_space_memory);
}
Exemplo n.º 4
0
/* FIXME: add a vq index parameter */
static void vhost_virtqueue_cleanup(struct vhost_dev *dev,
                                    struct VirtIODevice *vdev,
                                    struct vhost_virtqueue *vq,
                                    unsigned idx)
{
    struct vhost_vring_state state = {
        .index = idx % dev->nvqs,
    };
    int r;
    r = ioctl(dev->control, VHOST_GET_VRING_BASE, &state);
    if (r < 0) {
        fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r);
        fflush(stderr);
    }
    virtio_queue_set_last_avail_idx(vdev, idx, state.num);
    assert (r >= 0);
    cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
                              0, virtio_queue_get_ring_size(vdev, idx));
    cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx),
                              1, virtio_queue_get_used_size(vdev, idx));
    cpu_physical_memory_unmap(vq->avail, virtio_queue_get_avail_size(vdev, idx),
                              0, virtio_queue_get_avail_size(vdev, idx));
    cpu_physical_memory_unmap(vq->desc, virtio_queue_get_desc_size(vdev, idx),
                              0, virtio_queue_get_desc_size(vdev, idx));
}

static void vhost_eventfd_add(MemoryListener *listener,
                              MemoryRegionSection *section,
                              bool match_data, uint64_t data, int fd)
{
}

static void vhost_eventfd_del(MemoryListener *listener,
                              MemoryRegionSection *section,
                              bool match_data, uint64_t data, int fd)
{
}

int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force)
{
    uint64_t features;
    int r;
    if (devfd >= 0) {
        hdev->control = devfd;
    } else {
        hdev->control = open("/dev/vhost-net", O_RDWR);
        if (hdev->control < 0) {
            return -errno;
        }
    }
    r = ioctl(hdev->control, VHOST_SET_OWNER, NULL);
    if (r < 0) {
        goto fail;
    }

    r = ioctl(hdev->control, VHOST_GET_FEATURES, &features);
    if (r < 0) {
        goto fail;
    }
    hdev->features = features;

    hdev->memory_listener = (MemoryListener) {
        .begin = vhost_begin,
        .commit = vhost_commit,
        .region_add = vhost_region_add,
        .region_del = vhost_region_del,
        .region_nop = vhost_region_nop,
        .log_start = vhost_log_start,
        .log_stop = vhost_log_stop,
        .log_sync = vhost_log_sync,
        .log_global_start = vhost_log_global_start,
        .log_global_stop = vhost_log_global_stop,
        .eventfd_add = vhost_eventfd_add,
        .eventfd_del = vhost_eventfd_del,
        .priority = 10
    };
    hdev->mem = g_malloc0(offsetof(struct vhost_memory, regions));
    hdev->n_mem_sections = 0;
    hdev->mem_sections = NULL;
    hdev->log = NULL;
    hdev->log_size = 0;
    hdev->log_enabled = false;
    hdev->started = false;
    memory_listener_register(&hdev->memory_listener, NULL);
    hdev->force = force;
    return 0;
fail:
    r = -errno;
    close(hdev->control);
    return r;
}

void vhost_dev_cleanup(struct vhost_dev *hdev)
{
    memory_listener_unregister(&hdev->memory_listener);
    g_free(hdev->mem);
    g_free(hdev->mem_sections);
    close(hdev->control);
}