Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Minor fix to virtio networking
Lei Xia [Fri, 26 Feb 2010 21:14:21 +0000 (15:14 -0600)]
palacios/include/palacios/vmm_vnet.h
palacios/src/devices/lnx_virtio_nic.c
palacios/src/devices/vnet_nic.c
palacios/src/palacios/vmm_vnet.c

index c30c769..49951ad 100644 (file)
@@ -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
 
index d3d5cfb..8792174 100644 (file)
@@ -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) {
index ffe99df..abdd227 100644 (file)
@@ -25,7 +25,7 @@
 #include <devices/lnx_virtio_pci.h>
 #include <palacios/vm_guest_mem.h>
 #include <devices/pci.h>
-
+#include <palacios/vmm_sprintf.h>
 
 #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;
 }
 
index 137c4d8..d2602c5 100644 (file)
@@ -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;
 }