示例#1
0
static QVirtQueue *qvirtio_mmio_virtqueue_setup(QVirtioDevice *d,
                                        QGuestAllocator *alloc, uint16_t index)
{
    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
    QVirtQueue *vq;
    uint64_t addr;

    vq = g_malloc0(sizeof(*vq));
    qvirtio_mmio_queue_select(d, index);
    writel(dev->addr + QVIRTIO_MMIO_QUEUE_ALIGN, dev->page_size);

    vq->index = index;
    vq->size = qvirtio_mmio_get_queue_size(d);
    vq->free_head = 0;
    vq->num_free = vq->size;
    vq->align = dev->page_size;
    vq->indirect = (dev->features & (1u << VIRTIO_RING_F_INDIRECT_DESC)) != 0;
    vq->event = (dev->features & (1u << VIRTIO_RING_F_EVENT_IDX)) != 0;

    writel(dev->addr + QVIRTIO_MMIO_QUEUE_NUM, vq->size);

    /* Check different than 0 */
    g_assert_cmpint(vq->size, !=, 0);

    /* Check power of 2 */
    g_assert_cmpint(vq->size & (vq->size - 1), ==, 0);

    addr = guest_alloc(alloc, qvring_size(vq->size, dev->page_size));
    qvring_init(alloc, vq, addr);
    qvirtio_mmio_set_queue_address(d, vq->desc / dev->page_size);

    return vq;
}
示例#2
0
static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioDevice *d,
                                   QVirtioBlkReq *req, uint64_t data_size)
{
    uint64_t addr;
    uint8_t status = 0xFF;

    switch (req->type) {
    case VIRTIO_BLK_T_IN:
    case VIRTIO_BLK_T_OUT:
        g_assert_cmpuint(data_size % 512, ==, 0);
        break;
    case VIRTIO_BLK_T_DISCARD:
    case VIRTIO_BLK_T_WRITE_ZEROES:
        g_assert_cmpuint(data_size %
                         sizeof(struct virtio_blk_discard_write_zeroes), ==, 0);
        break;
    default:
        g_assert_cmpuint(data_size, ==, 0);
    }

    addr = guest_alloc(alloc, sizeof(*req) + data_size);

    virtio_blk_fix_request(d, req);

    memwrite(addr, req, 16);
    memwrite(addr + 16, req->data, data_size);
    memwrite(addr + 16 + data_size, &status, sizeof(status));

    return addr;
}
示例#3
0
/* This used to cause a NULL pointer dereference.  */
static void megasas_pd_get_info_fuzz(void *obj, void *data, QGuestAllocator *alloc)
{
    QMegasas *megasas = obj;
    QPCIDevice *dev = &megasas->dev;
    QPCIBar bar;
    uint32_t context[256];
    uint64_t context_pa;
    int i;

    qpci_device_enable(dev);
    bar = qpci_iomap(dev, 0, NULL);

    memset(context, 0, sizeof(context));
    context[0] = cpu_to_le32(0x05050505);
    context[1] = cpu_to_le32(0x01010101);
    for (i = 2; i < ARRAY_SIZE(context); i++) {
        context[i] = cpu_to_le32(0x41414141);
    }
    context[6] = cpu_to_le32(0x02020000);
    context[7] = cpu_to_le32(0);

    context_pa = guest_alloc(alloc, sizeof(context));
    memwrite(context_pa, context, sizeof(context));
    qpci_io_writel(dev, bar, 0x40, context_pa);
}
示例#4
0
static void v9fs_req_send(P9Req *req)
{
    QVirtIO9P *v9p = req->v9p;
    uint32_t free_head;

    req->r_msg = guest_alloc(v9p->qs->alloc, P9_MAX_SIZE);
    free_head = qvirtqueue_add(v9p->vq, req->t_msg, req->t_size, false, true);
    qvirtqueue_add(v9p->vq, req->r_msg, P9_MAX_SIZE, true, false);
    qvirtqueue_kick(v9p->dev, v9p->vq, free_head);
    req->t_off = 0;
}
示例#5
0
static uint64_t qvirtio_scsi_alloc(QVirtioSCSIQueues *vs, size_t alloc_size,
                                   const void *data)
{
    uint64_t addr;

    addr = guest_alloc(alloc, alloc_size);
    if (data) {
        memwrite(addr, data, alloc_size);
    }

    return addr;
}
示例#6
0
static P9Req *v9fs_req_init(QVirtIO9P *v9p, uint32_t size, uint8_t id,
                            uint16_t tag)
{
    P9Req *req = g_new0(P9Req, 1);
    uint32_t t_size = 7 + size; /* 9P header has well-known size of 7 bytes */
    P9Hdr hdr = {
        .size = cpu_to_le32(t_size),
        .id = id,
        .tag = cpu_to_le16(tag)
    };

    g_assert_cmpint(t_size, <=, P9_MAX_SIZE);

    req->v9p = v9p;
    req->t_size = t_size;
    req->t_msg = guest_alloc(v9p->qs->alloc, req->t_size);
    v9fs_memwrite(req, &hdr, 7);
    req->tag = tag;
    return req;
}
示例#7
0
文件: virtio.c 项目: chao-p/qemu
QVRingIndirectDesc *qvring_indirect_desc_setup(QVirtioDevice *d,
                                        QGuestAllocator *alloc, uint16_t elem)
{
    int i;
    QVRingIndirectDesc *indirect = g_malloc(sizeof(*indirect));

    indirect->index = 0;
    indirect->elem = elem;
    indirect->desc = guest_alloc(alloc, sizeof(QVRingDesc)*elem);

    for (i = 0; i < elem - 1; ++i) {
        /* indirect->desc[i].addr */
        writeq(indirect->desc + (16 * i), 0);
        /* indirect->desc[i].flags */
        writew(indirect->desc + (16 * i) + 12, QVRING_DESC_F_NEXT);
        /* indirect->desc[i].next */
        writew(indirect->desc + (16 * i) + 14, i + 1);
    }

    return indirect;
}
示例#8
0
    uint32_t free_head;
    char test[] = "TEST";
    char buffer[64];
    int len = htonl(sizeof(test));
    struct iovec iov[] = {
        {
            .iov_base = &len,
            .iov_len = sizeof(len),
        }, {
            .iov_base = test,
            .iov_len = sizeof(test),
        },
    };
    int ret;

    req_addr = guest_alloc(alloc, 64);

    free_head = qvirtqueue_add(vq, req_addr, 64, true, false);
    qvirtqueue_kick(bus, dev, vq, free_head);

    ret = iov_send(socket, iov, 2, 0, sizeof(len) + sizeof(test));
    g_assert_cmpint(ret, ==, sizeof(test) + sizeof(len));

    qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_NET_TIMEOUT_US);
    memread(req_addr + VNET_HDR_SIZE, buffer, sizeof(test));
    g_assert_cmpstr(buffer, ==, "TEST");

    guest_free(alloc, req_addr);
}

static void tx_test(const QVirtioBus *bus, QVirtioDevice *dev,