X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Flnx_virtio_blk.c;h=a8dba1cd78fc56bb1b665ee62e1d393d6ffa598b;hb=e61e0890e6f13b1362cfffdcd287e90f1d41e443;hp=2c871d9d2b0d1c55925c909836f65fc32f828a67;hpb=6d6988cc9c8bac21d96afd800076afe0915cf2cd;p=palacios.git diff --git a/palacios/src/devices/lnx_virtio_blk.c b/palacios/src/devices/lnx_virtio_blk.c index 2c871d9..a8dba1c 100644 --- a/palacios/src/devices/lnx_virtio_blk.c +++ b/palacios/src/devices/lnx_virtio_blk.c @@ -26,7 +26,7 @@ -#ifndef CONFIG_DEBUG_VIRTIO_BLK +#ifndef V3_CONFIG_DEBUG_VIRTIO_BLK #undef PrintDebug #define PrintDebug(fmt, args...) #endif @@ -285,7 +285,7 @@ static int handle_kick(struct guest_info * core, struct virtio_blk_state * blk_s if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) { PrintDebug("Raising IRQ %d\n", blk_state->pci_dev->config_header.intr_line); - v3_pci_raise_irq(blk_state->virtio_dev->pci_bus, 0, blk_state->pci_dev); + v3_pci_raise_irq(blk_state->virtio_dev->pci_bus, blk_state->pci_dev, 0); blk_state->virtio_cfg.pci_isr = 1; } @@ -407,38 +407,44 @@ static int virtio_io_read(struct guest_info * core, uint16_t port, void * dst, u PrintDebug("VIRTIO BLOCK Read for port %d (index =%d), length=%d\n", port, port_idx, length); + switch (port_idx) { case HOST_FEATURES_PORT: - if (length != 4) { - PrintError("Illegal read length for host features\n"); + case HOST_FEATURES_PORT + 1: + case HOST_FEATURES_PORT + 2: + case HOST_FEATURES_PORT + 3: + if (port_idx + length > HOST_FEATURES_PORT + 4) { + PrintError("Illegal read length for host features (len=%d)\n", length); return -1; } - *(uint32_t *)dst = blk_state->virtio_cfg.host_features; - + memcpy(dst, &(blk_state->virtio_cfg.host_features), length); break; case VRING_PG_NUM_PORT: - if (length != 4) { - PrintError("Illegal read length for page frame number\n"); + case VRING_PG_NUM_PORT + 1: + case VRING_PG_NUM_PORT + 2: + case VRING_PG_NUM_PORT + 3: + if (port_idx + length > VRING_PG_NUM_PORT + 4) { + PrintError("Illegal read length for vring pg num (len=%d)\n", length); return -1; } - *(uint32_t *)dst = blk_state->queue.pfn; - + memcpy(dst, &(blk_state->queue.pfn), length); break; case VRING_SIZE_PORT: - if (length != 2) { - PrintError("Illegal read length for vring size\n"); + case VRING_SIZE_PORT + 1: + if (length > 2) { + PrintError("Illegal read length for vring size (len=%d)\n", length); return -1; } - - *(uint16_t *)dst = blk_state->queue.queue_size; + + memcpy(dst, &(blk_state->queue.queue_size), length); break; case VIRTIO_STATUS_PORT: if (length != 1) { - PrintError("Illegal read length for status\n"); + PrintError("Illegal read length for status (len=%d)\n", length); return -1; } @@ -448,7 +454,7 @@ static int virtio_io_read(struct guest_info * core, uint16_t port, void * dst, u case VIRTIO_ISR_PORT: *(uint8_t *)dst = blk_state->virtio_cfg.pci_isr; blk_state->virtio_cfg.pci_isr = 0; - v3_pci_lower_irq(blk_state->virtio_dev->pci_bus, 0, blk_state->pci_dev); + v3_pci_lower_irq(blk_state->virtio_dev->pci_bus, blk_state->pci_dev, 0); break; default: @@ -472,7 +478,18 @@ static int virtio_io_read(struct guest_info * core, uint16_t port, void * dst, u static int virtio_free(struct virtio_dev_state * virtio) { + struct virtio_blk_state * blk_state = NULL; + struct virtio_blk_state * tmp = NULL; + + list_for_each_entry_safe(blk_state, tmp, &(virtio->dev_list), dev_link) { + + // unregister from PCI + + list_del(&(blk_state->dev_link)); + V3_Free(blk_state); + } + V3_Free(virtio); return 0; @@ -531,7 +548,7 @@ static int register_dev(struct virtio_dev_state * virtio, struct virtio_blk_stat pci_dev = v3_pci_register_device(virtio->pci_bus, PCI_STD_DEVICE, 0, PCI_AUTO_DEV_NUM, 0, "LNX_VIRTIO_BLK", bars, - NULL, NULL, NULL, blk_state); + NULL, NULL, NULL, NULL, blk_state); if (!pci_dev) { PrintError("Could not register PCI Device\n"); @@ -555,6 +572,10 @@ static int register_dev(struct virtio_dev_state * virtio, struct virtio_blk_stat blk_state->pci_dev = pci_dev; + + + /* Add backend to list of devices */ + list_add(&(blk_state->dev_link), &(virtio->dev_list)); /* Block configuration */ blk_state->virtio_cfg.host_features = VIRTIO_SEG_MAX; @@ -581,6 +602,13 @@ static int connect_fn(struct v3_vm_info * vm, struct virtio_dev_state * virtio = (struct virtio_dev_state *)frontend_data; struct virtio_blk_state * blk_state = (struct virtio_blk_state *)V3_Malloc(sizeof(struct virtio_blk_state)); + + if (!blk_state) { + PrintError("Cannot allocate in connect\n"); + return -1; + } + + memset(blk_state, 0, sizeof(struct virtio_blk_state)); register_dev(virtio, blk_state); @@ -611,6 +639,12 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { virtio_state = (struct virtio_dev_state *)V3_Malloc(sizeof(struct virtio_dev_state)); + + if (!virtio_state) { + PrintError("Cannot allocate in init\n"); + return -1; + } + memset(virtio_state, 0, sizeof(struct virtio_dev_state)); INIT_LIST_HEAD(&(virtio_state->dev_list));