From: Lei Xia Date: Fri, 26 Feb 2010 21:14:21 +0000 (-0600) Subject: Minor fix to virtio networking X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=ac31dc84e5e31187345ec6d66647b29975958a94;p=palacios.git Minor fix to virtio networking --- diff --git a/palacios/include/palacios/vmm_vnet.h b/palacios/include/palacios/vmm_vnet.h index c30c769..49951ad 100644 --- a/palacios/include/palacios/vmm_vnet.h +++ b/palacios/include/palacios/vmm_vnet.h @@ -89,9 +89,6 @@ int v3_vnet_add_dev(struct v3_vm_info *info, uint8_t mac[6], void * priv_data); -// temporary hack -int v3_vnet_pkt_process(); - #endif diff --git a/palacios/src/devices/lnx_virtio_nic.c b/palacios/src/devices/lnx_virtio_nic.c index d3d5cfb..8792174 100644 --- a/palacios/src/devices/lnx_virtio_nic.c +++ b/palacios/src/devices/lnx_virtio_nic.c @@ -66,7 +66,7 @@ struct virtio_net_config struct virtio_dev_state { struct vm_device * pci_bus; struct list_head dev_list; - struct guest_info *vm; + struct v3_vm_info *vm; }; struct virtio_net_state { @@ -131,14 +131,14 @@ static int virtio_init_state(struct virtio_net_state * virtio) return 0; } -static int pkt_tx(struct virtio_net_state * virtio, struct vring_desc * buf_desc) +static int pkt_tx(struct guest_info *core, struct virtio_net_state * virtio, struct vring_desc * buf_desc) { uint8_t * buf = NULL; uint32_t len = buf_desc->length; - PrintDebug("Virtio NIC: Handling Virtio Write, net_state: %p\n", virtio); + PrintDebug("Virtio NIC: Virtio Pkt Sending, net_state: %p, pkt size: %d\n", virtio, len); - if (guest_pa_to_host_va(virtio->virtio_dev->vm, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) { + if (guest_pa_to_host_va(core, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) { PrintError("Could not translate buffer address\n"); return -1; } @@ -162,12 +162,16 @@ static int build_receive_header(struct virtio_net_hdr * hdr, const void * buf, i return 0; } -static int copy_data_to_desc(struct virtio_net_state * virtio_state, struct vring_desc * desc, uchar_t * buf, uint_t buf_len) +static int copy_data_to_desc(struct guest_info *core, + struct virtio_net_state * virtio_state, + struct vring_desc * desc, + uchar_t * buf, + uint_t buf_len) { uint32_t len; uint8_t * desc_buf = NULL; - if (guest_pa_to_host_va(virtio_state->virtio_dev->vm, desc->addr_gpa, (addr_t *)&(desc_buf)) == -1) { + if (guest_pa_to_host_va(core, desc->addr_gpa, (addr_t *)&(desc_buf)) == -1) { PrintError("Could not translate buffer address\n"); return -1; } @@ -192,11 +196,11 @@ static int get_desc_count(struct virtio_queue * q, int index) { return cnt; } -static int handle_ctrl(struct virtio_net_state * dev) { +static int handle_ctrl(struct guest_info *core, struct virtio_net_state * dev) { return 0; } -static int handle_pkt_tx(struct virtio_net_state * virtio_state) +static int handle_pkt_tx(struct guest_info *core, struct virtio_net_state * virtio_state) { struct virtio_queue * q = &(virtio_state->tx_vq); struct virtio_net_hdr * hdr = NULL; @@ -217,7 +221,7 @@ static int handle_pkt_tx(struct virtio_net_state * virtio_state) int i = 0; hdr_desc = &(q->desc[desc_idx]); - if (guest_pa_to_host_va(virtio_state->virtio_dev->vm, hdr_desc->addr_gpa, &(hdr_addr)) == -1) { + if (guest_pa_to_host_va(core, hdr_desc->addr_gpa, &(hdr_addr)) == -1) { PrintError("Could not translate block header address\n"); return -1; } @@ -227,7 +231,7 @@ static int handle_pkt_tx(struct virtio_net_state * virtio_state) for (i = 0; i < desc_cnt - 1; i++) { struct vring_desc * buf_desc = &(q->desc[desc_idx]); - if (pkt_tx(virtio_state, buf_desc) == -1) { + if (pkt_tx(core, virtio_state, buf_desc) == -1) { PrintError("Error handling nic operation\n"); return -1; } @@ -263,7 +267,12 @@ static int handle_pkt_tx(struct virtio_net_state * virtio_state) return 0; } -static int virtio_setup_queue(struct virtio_net_state * virtio_state, struct virtio_queue * queue, addr_t pfn, addr_t page_addr) { + +static int virtio_setup_queue(struct guest_info *core, + struct virtio_net_state * virtio_state, + struct virtio_queue * queue, + addr_t pfn, + addr_t page_addr) { queue->pfn = pfn; queue->ring_desc_addr = page_addr; @@ -271,24 +280,32 @@ static int virtio_setup_queue(struct virtio_net_state * virtio_state, struct vir queue->ring_used_addr = ((queue->ring_avail_addr) + (sizeof(struct vring_avail)) + (queue->queue_size * sizeof(uint16_t))); - + + PrintDebug("Virtio NIC: In setup queue: queue %p\n", (void *)queue); + // round up to next page boundary. queue->ring_used_addr = (queue->ring_used_addr + 0xfff) & ~0xfff; - if (guest_pa_to_host_va(virtio_state->virtio_dev->vm, queue->ring_desc_addr, (addr_t *)&(queue->desc)) == -1) { + if (guest_pa_to_host_va(core, queue->ring_desc_addr, (addr_t *)&(queue->desc)) == -1) { PrintError("Could not translate ring descriptor address\n"); return -1; } + + PrintDebug("Virtio NIC: In setup queue111: queue %p\n", (void *)queue); - if (guest_pa_to_host_va(virtio_state->virtio_dev->vm, queue->ring_avail_addr, (addr_t *)&(queue->avail)) == -1) { + if (guest_pa_to_host_va(core, queue->ring_avail_addr, (addr_t *)&(queue->avail)) == -1) { PrintError("Could not translate ring available address\n"); return -1; } - if (guest_pa_to_host_va(virtio_state->virtio_dev->vm, queue->ring_used_addr, (addr_t *)&(queue->used)) == -1) { + PrintDebug("Virtio NIC: In setup queue222: queue %p\n", (void *)queue); + + if (guest_pa_to_host_va(core, queue->ring_used_addr, (addr_t *)&(queue->used)) == -1) { PrintError("Could not translate ring used address\n"); return -1; } + PrintDebug("Virtio NIC: In setup queue333: queue %p\n", (void *)queue); + PrintDebug("RingDesc_addr=%p, Avail_addr=%p, Used_addr=%p\n", (void *)(queue->ring_desc_addr), (void *)(queue->ring_avail_addr), @@ -326,15 +343,18 @@ static int virtio_io_write(struct guest_info *core, uint16_t port, void * src, u addr_t pfn = *(uint32_t *)src; addr_t page_addr = (pfn << VIRTIO_PAGE_SHIFT); uint16_t queue_idx = virtio->virtio_cfg.vring_queue_selector; + + PrintDebug("Virtio Write: pfn: %p, page_addr %p, queue_idx %d\n", (void *)pfn, (void *)page_addr, queue_idx); + switch (queue_idx) { case 0: - virtio_setup_queue(virtio, &virtio->rx_vq, pfn, page_addr); + virtio_setup_queue(core, virtio, &virtio->rx_vq, pfn, page_addr); break; case 1: - virtio_setup_queue(virtio, &virtio->tx_vq, pfn, page_addr); + virtio_setup_queue(core, virtio, &virtio->tx_vq, pfn, page_addr); break; case 2: - virtio_setup_queue(virtio, &virtio->ctrl_vq, pfn, page_addr); + virtio_setup_queue(core, virtio, &virtio->ctrl_vq, pfn, page_addr); break; default: break; @@ -356,12 +376,12 @@ static int virtio_io_write(struct guest_info *core, uint16_t port, void * src, u if (queue_idx == 0){ PrintDebug("receive queue notification 0, packet get by Guest\n"); } else if (queue_idx == 1){ - if (handle_pkt_tx(virtio) == -1) { + if (handle_pkt_tx(core, virtio) == -1) { PrintError("Could not handle NIC Notification\n"); return -1; } } else if (queue_idx == 2){ - if (handle_ctrl(virtio) == -1) { + if (handle_ctrl(core, virtio) == -1) { PrintError("Could not handle NIC Notification\n"); return -1; } @@ -397,7 +417,7 @@ static int virtio_io_read(struct guest_info *core, uint16_t port, void * dst, ui int port_idx = port % virtio->io_range_size; uint16_t queue_idx = virtio->virtio_cfg.vring_queue_selector; - PrintDebug("Virtio NIC %p: Read for port %d (index =%d), length=%d", private_data, + PrintDebug("Virtio NIC %p: Read for port %d (index =%d), length=%d\n", private_data, port, port_idx, length); switch (port_idx) { @@ -483,10 +503,11 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) { uint32_t data_len = size; uint32_t offset = 0; unsigned long flags; + int ret_val; flags = v3_lock_irqsave(virtio->lock); - PrintDebug("VIRTIO NIC: sending packet to virtio nic %p, size:%d", virtio, size); + PrintDebug("VIRTIO NIC: receiving packet to virtio nic %p, size:%d\n", virtio, size); virtio->pkt_recv ++; data_len -= hdr_len; @@ -495,7 +516,8 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) { if (q->ring_avail_addr == 0) { PrintError("Queue is not set\n"); - return -1; + ret_val = -1; + goto exit; } if (q->last_avail_idx > q->avail->index) @@ -509,9 +531,10 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) { struct vring_desc * hdr_desc = NULL; hdr_desc = &(q->desc[hdr_idx]); - if (guest_pa_to_host_va(virtio->virtio_dev->vm, hdr_desc->addr_gpa, &(hdr_addr)) == -1) { + if (guest_pa_to_host_va(&(virtio->virtio_dev->vm->cores[0]), hdr_desc->addr_gpa, &(hdr_addr)) == -1) { PrintError("Could not translate receive buffer address\n"); - return -1; + ret_val = -1; + goto exit; } memcpy((void *)hdr_addr, &hdr, sizeof(struct virtio_net_hdr)); @@ -523,7 +546,7 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) { struct vring_desc * buf_desc = &(q->desc[buf_idx]); uint32_t len = 0; - len = copy_data_to_desc(virtio, buf_desc, buf + offset, data_len - offset); + len = copy_data_to_desc(&(virtio->virtio_dev->vm->cores[0]), virtio, buf_desc, buf + offset, data_len - offset); offset += len; if (offset < data_len) { buf_desc->flags = VIRTIO_NEXT_FLAG; @@ -561,9 +584,13 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) { } #endif + ret_val = offset; + +exit: + v3_unlock_irqrestore(virtio->lock, flags); - - return offset; + + return ret_val; } @@ -680,6 +707,7 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { INIT_LIST_HEAD(&(virtio_state->dev_list)); virtio_state->pci_bus = pci_bus; + virtio_state->vm = vm; struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state); if (v3_attach_device(vm, dev) == -1) { diff --git a/palacios/src/devices/vnet_nic.c b/palacios/src/devices/vnet_nic.c index ffe99df..abdd227 100644 --- a/palacios/src/devices/vnet_nic.c +++ b/palacios/src/devices/vnet_nic.c @@ -25,7 +25,7 @@ #include #include #include - +#include #ifndef CONFIG_DEBUG_VNET_NIC #undef PrintDebug @@ -41,10 +41,13 @@ struct vnet_nic_state { //used when virtio_nic get a packet from guest and send it to the backend static int vnet_send(uint8_t * buf, uint32_t len, void * private_data, struct vm_device *dest_dev){ - PrintDebug("Virito NIC: In vnet_send: guest net state %p\n", private_data); - struct v3_vnet_pkt * pkt = NULL; + struct v3_vnet_pkt * pkt = NULL; + + PrintDebug("Virtio VNET-NIC: send pkt size: %d\n", len); +#ifdef CONFIG_DEBUG_VNET_NIC + v3_hexdump(buf, len, NULL, 0); +#endif - // fill in packet pkt = (struct v3_vnet_pkt *)V3_Malloc(sizeof(struct v3_vnet_pkt)); if(pkt == NULL){ @@ -55,9 +58,9 @@ static int vnet_send(uint8_t * buf, uint32_t len, void * private_data, struct vm pkt->size = len; memcpy(pkt->data, buf, pkt->size); - //TODO: - v3_vnet_send_pkt(pkt); + + V3_Free(pkt); return 0; } diff --git a/palacios/src/palacios/vmm_vnet.c b/palacios/src/palacios/vmm_vnet.c index 137c4d8..d2602c5 100644 --- a/palacios/src/palacios/vmm_vnet.c +++ b/palacios/src/palacios/vmm_vnet.c @@ -98,13 +98,6 @@ static struct { #ifdef CONFIG_DEBUG_VNET - -static void print_packet(struct v3_vnet_pkt * pkt) { - PrintDebug("Vnet: data_packet: size: %d\n", pkt->size); - v3_hexdump(pkt->data, pkt->size, NULL, 0); -} - - static inline void mac_to_string(char mac[6], char * buf) { snprintf(buf, 20, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], @@ -367,6 +360,7 @@ static int handle_one_pkt(struct v3_vnet_pkt * pkt) { add_route_to_cache(pkt, matched_routes); } else { PrintError("Could not find route for packet...\n"); + v3_unlock_irqrestore(vnet_state.lock, flags); return -1; } } @@ -396,18 +390,15 @@ static int handle_one_pkt(struct v3_vnet_pkt * pkt) { } int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt) { - // find the destination and call the send packet function, passing pkt * - + + PrintDebug("In Vnet Send: pkt size: %d\n", pkt->size); + if (handle_one_pkt(pkt) != -1) { PrintDebug("VNET: send one packet! pt length %d\n", pkt->size); } else { PrintDebug("VNET: Fail to forward one packet, discard it!\n"); } -#ifdef CONFIG_DEBUG_VNET - print_packet(pkt); -#endif - return 0; } @@ -418,6 +409,8 @@ int v3_vnet_add_dev(struct v3_vm_info *vm,uint8_t mac[6], new_dev = find_dev_by_mac(mac); + PrintDebug("VNET: register device\n"); + if (new_dev) { PrintDebug("VNET: register device: Already has device with the same mac\n"); return -1; @@ -429,15 +422,14 @@ int v3_vnet_add_dev(struct v3_vm_info *vm,uint8_t mac[6], PrintError("VNET: Malloc fails\n"); return -1; } - + memcpy(new_dev->mac_addr, mac, 6); new_dev->input = netif_input; new_dev->private_data = priv_data; new_dev->vm = vm; - // ADD TO dev list - // increment dev count - + PrintDebug("VNET: register device new_dev22 %p\n", (void *)new_dev); + list_add(&(new_dev->node), &(vnet_state.devs)); vnet_state.num_devs ++; new_dev->dev_id = vnet_state.num_devs; @@ -445,7 +437,8 @@ int v3_vnet_add_dev(struct v3_vm_info *vm,uint8_t mac[6], return 0; } -int v3_vnet_pkt_process() { +#if 0 +static int v3_vnet_pkt_process() { struct v3_vnet_pkt * pkt = NULL; while ((pkt = (struct v3_vnet_pkt *)v3_dequeue(vnet_state.inpkt_q)) != NULL) { @@ -460,23 +453,23 @@ int v3_vnet_pkt_process() { return 0; } - +#endif int V3_init_vnet() { - - PrintDebug("VNET: Links table initiated\n"); - + INIT_LIST_HEAD(&(vnet_state.routes)); INIT_LIST_HEAD(&(vnet_state.devs)); vnet_state.num_devs = 0; vnet_state.num_routes = 0; + PrintDebug("VNET: Links and Routes tables initiated\n"); + if (v3_lock_init(&(vnet_state.lock)) == -1){ PrintError("VNET: Failure to init lock for routes table\n"); } - PrintDebug("VNET: Routes table initiated\n"); + PrintDebug("VNET: Locks initiated\n"); /*initial pkt receiving queue */ vnet_state.inpkt_q = v3_create_queue(); @@ -490,5 +483,7 @@ int V3_init_vnet() { return -1; } + PrintDebug("VNET: initiated\n"); + return 0; }