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.


Merge branch 'devel' of ssh://palacios@newskysaw.cs.northwestern.edu/home/palacios...
Lei Xia [Fri, 12 Mar 2010 16:38:43 +0000 (10:38 -0600)]
Conflicts:
palacios/src/devices/lnx_virtio_vnet.c

1  2 
palacios/include/palacios/vm_guest.h
palacios/include/palacios/vmm_vnet.h
palacios/src/devices/lnx_virtio_nic.c
palacios/src/devices/lnx_virtio_vnet.c
palacios/src/devices/vnet_nic.c
palacios/src/palacios/vm_guest_mem.c
palacios/src/palacios/vmx_handler.c
utils/guest_creator/default.xml

@@@ -41,8 -41,8 +41,9 @@@
  #endif
  
  
--
--
++#ifdef CONFIG_VNET
++#include <palacios/vmm_vnet.h>
++#endif
  
  
  #ifdef CONFIG_SYMBIOTIC
@@@ -113,6 -113,6 +114,10 @@@ struct guest_info 
      struct v3_vm_info * vm_info;
      // the logical cpu this guest context is executing on
      int cpu_id;
++
++#ifdef CONFIG_VNET_PROFILE
++    struct v3_vnet_profile vnet_times;
++#endif
  };
  
  
@@@ -26,8 -26,8 +26,8 @@@
  
  #include <palacios/vmm.h>
  
--typedef enum {MAC_ANY, MAC_NOT, MAC_NONE} mac_type_t; //for 'src_mac_qual' and 'dst_mac_qual'
--typedef enum {LINK_INTERFACE, LINK_EDGE, LINK_ANY} link_type_t; //for 'type' and 'src_type' in struct routing
++typedef enum {MAC_ANY=0, MAC_NOT, MAC_NONE, MAC_ADDR} mac_type_t; //for 'src_mac_qual' and 'dst_mac_qual'
++typedef enum {LINK_INTERFACE=0, LINK_EDGE, LINK_ANY} link_type_t; //for 'type' and 'src_type' in struct routing
  
  
  #define VNET_HASH_SIZE 17
@@@ -146,7 -146,7 +146,7 @@@ static int pkt_tx(struct guest_info *co
        return -1;
      }
  
--    if (virtio->net_ops->send(buf, len, (void *)core, NULL) == -1) {
++    if (virtio->net_ops->send(buf, len, virtio->backend_data, NULL) == -1) {
        return -1;
      }
  
@@@ -26,7 -26,7 +26,7 @@@
  #include <devices/pci.h>
  
  
- #ifndef CONFIG_DEBUG_VNET_BRG
+ #ifndef CONFIG_LINUX_VIRTIO_VNET_DEBUG
  #undef PrintDebug
  #define PrintDebug(fmt, args...)
  #endif
@@@ -42,11 -42,11 +42,11 @@@ struct vnet_config 
  
  
  #define CTRL_QUEUE 0
- #define RECV_QUEUE 2
  #define XMIT_QUEUE 1
+ #define RECV_QUEUE 2
  
  struct virtio_vnet_state {
-     struct v3_vm_info *vm;
+     struct v3_vm_info * vm;
      struct vnet_config vnet_cfg;
      struct virtio_config virtio_cfg;
  
@@@ -75,21 -75,28 +75,27 @@@ struct vnet_ctrl_hdr 
      uint32_t num_cmds;
  } __attribute__((packed));
  
- static int vnetbrg_reset(struct virtio_vnet_state * vnet_brg) {
 -
+ struct vnet_virtio_pkt {
+     uint32_t link_id;
+     uint32_t pkt_size;
+     uint8_t pkt[1500];
+ };
  
-     memset(vnet_brg->queue, 0, sizeof(struct virtio_queue) * 2);
+ static int virtio_reset(struct virtio_vnet_state * vnet_state) {
  
-     vnet_brg->cur_queue = &(vnet_brg->queue[0]);
+     memset(vnet_state->queue, 0, sizeof(struct virtio_queue) * 2);
  
-     vnet_brg->virtio_cfg.status = 0;
-     vnet_brg->virtio_cfg.pci_isr = 0;
+     vnet_state->cur_queue = &(vnet_state->queue[0]);
  
-     vnet_brg->queue[0].queue_size = QUEUE_SIZE;
-     vnet_brg->queue[1].queue_size = QUEUE_SIZE;
-     vnet_brg->queue[2].queue_size = QUEUE_SIZE;
+     vnet_state->virtio_cfg.status = 0;
+     vnet_state->virtio_cfg.pci_isr = 0;
  
-     memset(&(vnet_brg->vnet_cfg), 0, sizeof(struct vnet_config));
-     v3_lock_init(&(vnet_brg->lock));
+     vnet_state->queue[0].queue_size = QUEUE_SIZE;
+     vnet_state->queue[1].queue_size = QUEUE_SIZE;
+     vnet_state->queue[2].queue_size = QUEUE_SIZE;
+     memset(&(vnet_state->vnet_cfg), 0, sizeof(struct vnet_config));
+     v3_lock_init(&(vnet_state->lock));
  
      return 0;
  }
@@@ -116,7 -123,7 +122,7 @@@ static int handle_cmd_kick(struct guest
      
      PrintDebug("VNET Bridge: Handling command  queue\n");
  
-     while (q->cur_avail_idx < q->avail->index) {
+     while (q->cur_avail_idx != q->avail->index) {
        struct vring_desc * hdr_desc = NULL;
        struct vring_desc * buf_desc = NULL;
        struct vring_desc * status_desc = NULL;
        uint8_t status = 0;
  
  
 -      PrintDebug("Descriptor Count=%d, index=%d, desc_idx=%d\n", desc_cnt, q->cur_avail_idx % QUEUE_SIZE, desc_idx);
 +      PrintDebug("VNET Bridge: CMD: Descriptor Count=%d, index=%d, desc_idx=%d\n", desc_cnt, q->cur_avail_idx % QUEUE_SIZE, desc_idx);
  
        if (desc_cnt < 3) {
            PrintError("VNET Bridge cmd must include at least 3 descriptors (cnt=%d)\n", desc_cnt);
                }
  
                // add route
 -              PrintDebug("Adding VNET Route\n");
 +              PrintDebug("VNET Bridge: Adding VNET Route\n");
  
                tmp_status = v3_vnet_add_route(*route);
  
      return 0;
  }
  
- static int copy_data_to_desc(struct guest_info *core, 
-                                       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(core, desc->addr_gpa, (addr_t *)&(desc_buf)) == -1) {
-       PrintError("Could not translate buffer address\n");
-       return -1;
-     }
-     len = (desc->length < buf_len)?desc->length:buf_len;
-     memcpy(desc_buf, buf, len);
-     return len;
- }
- static int vnet_brg_rx(struct v3_vnet_pkt *pkt, void * private_data) {
-     struct virtio_vnet_state * vnet_brg = (struct virtio_vnet_state *)private_data;
-     struct virtio_queue * q = &(vnet_brg->queue[RECV_QUEUE]);
-     char *buf = (char *)pkt;
-     int ret_val;
-     int pkt_head_len = ((addr_t)pkt->data) - ((addr_t)pkt); 
-     uint32_t data_len = sizeof(struct v3_vnet_pkt); //TODO: should not transfer the whole struct, only the data size 
+ static int vnet_pkt_input_cb(struct v3_vm_info * vm,  struct v3_vnet_pkt * pkt,  void * private_data){
+     struct virtio_vnet_state * vnet_state = (struct virtio_vnet_state *)private_data;
+     struct virtio_queue * q = &(vnet_state->queue[RECV_QUEUE]);
+     int ret_val = -1;
      unsigned long flags;
  
-     flags = v3_lock_irqsave(vnet_brg->lock);
+     flags = v3_lock_irqsave(vnet_state->lock);
        
      PrintDebug("VNET Bridge: RX: pkt sent to guest size: %d\n, pkt_header_len: %d\n", data_len, pkt_head_len);
  
      if (q->ring_avail_addr == 0) {
        PrintError("Queue is not set\n");
        goto exit;
      }
  
-     if (q->last_avail_idx > q->avail->index)
-       q->idx_overflow = true;
-     q->last_avail_idx = q->avail->index;
  
-     if (q->cur_avail_idx < q->avail->index || (q->idx_overflow && q->cur_avail_idx < q->avail->index+65536)){
-       uint16_t buf_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
-       uint32_t len = 0;
-       uint32_t offset = 0;
-       struct vring_desc * buf_desc = NULL;
+     if (q->cur_avail_idx != q->avail->index) {
+       uint16_t pkt_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
+       struct vring_desc * pkt_desc = NULL;
+       struct vnet_virtio_pkt * virtio_pkt = NULL;
  
-       buf_desc = &(q->desc[buf_idx]);
-       PrintDebug("VNET Bridge RX: buffer desc len: %d\n", buf_desc->length);
  
-       len = copy_data_to_desc(&(vnet_brg->vm->cores[0]), buf_desc, buf + offset, data_len - offset);
-       if (len == -1) {
-           ret_val = -1;
-           goto exit;
-       }
-       offset += len;
-       buf_desc->length = len;
-       
-       if (offset >= data_len) {
-           buf_desc->flags &= ~VIRTIO_NEXT_FLAG;
-       }else {
-           PrintDebug("VNET Bridge: RX: Pkt not fit into one desc buf\n");
+       pkt_desc = &(q->desc[pkt_idx]);
+       PrintDebug("VNET Bridge RX: buffer desc len: %d\n", pkt_desc->length);
+       if (guest_pa_to_host_va(&(vm->cores[0]), pkt_desc->addr_gpa, (addr_t *)&(virtio_pkt)) == -1) {
+           PrintError("Could not translate buffer address\n");
+           return -1;
        }
  
+       // Fill in dst packet buffer
+       virtio_pkt->link_id = pkt->dst_id;
+       virtio_pkt->pkt_size = pkt->size;
+       memcpy(virtio_pkt->pkt, pkt->data, pkt->size);
+       
        q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
-       q->used->ring[q->used->index % q->queue_size].length = data_len; // This should be the total length of data sent to guest (header+pkt_data)
-       q->used->index++;
+       q->used->ring[q->used->index % q->queue_size].length = sizeof(struct vnet_virtio_pkt); // This should be the total length of data sent to guest (header+pkt_data)
  
-       int last_idx = q->cur_avail_idx;
+       q->used->index++;
        q->cur_avail_idx++;
-       if (q->cur_avail_idx < last_idx)
-           q->idx_overflow = false;
      } else {
-       PrintDebug("VNET Bridge: Handle RX: Fails to send, no available buffer: current_idx:%d, availIdx: %d\n", q->cur_avail_idx, q->avail->index);
+       PrintError("Packet buffer overflow in the guest\n");
      }
  
      if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
-       v3_pci_raise_irq(vnet_brg->pci_bus, 0, vnet_brg->pci_dev);
-       vnet_brg->virtio_cfg.pci_isr = 0x1;
-       PrintDebug("Raising IRQ %d\n",  vnet_brg->pci_dev->config_header.intr_line);
+       v3_pci_raise_irq(vnet_state->pci_bus, 0, vnet_state->pci_dev);
+       vnet_state->virtio_cfg.pci_isr = 0x1;
+       PrintDebug("Raising IRQ %d\n",  vnet_state->pci_dev->config_header.intr_line);
      }
  
      ret_val = 0;
  
  exit:
-     v3_unlock_irqrestore(vnet_brg->lock, flags);
+     v3_unlock_irqrestore(vnet_state->lock, flags);
   
      return ret_val;
  }
  
- static int vnet_send(struct v3_vnet_pkt *pkt, int pkt_len, void * private_data){
-     struct virtio_vnet_state *vnet_brg  = (struct virtio_vnet_state *)private_data; 
-     struct guest_info *core = &(vnet_brg->vm->cores[0]);
- #ifdef CONFIG_DEBUG_VNET_BRG
-     {
-       PrintDebug("VNET Bridge: send pkt size: %d, src_id: %d, src_type: %d\n", 
-                       pkt->size, pkt->src_id, pkt->src_type);
-       v3_hexdump(pkt->data,pkt->size, NULL, 0);
-     }
- #endif
- #ifdef CONFIG_VNET_PROFILE
-     uint64_t time;
-     rdtscll(time);
-     core->vnet_times.time_copy_from_guest = time - core->vnet_times.virtio_handle_start;
- #endif
-     pkt->src_type = LINK_EDGE;
-     v3_vnet_send_pkt(pkt, (void *)core);
-     return 0;
- //v3_vnet_send_pkt(pkt, (void *)core);
- }
- static int pkt_tx(struct guest_info *core, struct virtio_vnet_state * vnet_brg, struct vring_desc * buf_desc) 
- {
-     uint8_t * buf = NULL;
-     uint32_t len = buf_desc->length;
-     struct v3_vnet_pkt *pkt;
-     if (guest_pa_to_host_va(core, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) {
-       PrintError("Could not translate buffer address\n");
-       return -1;
-     }
-  
-     pkt = (struct v3_vnet_pkt *)buf;
-     if (vnet_send(pkt, len, vnet_brg) == -1) {
-       return -1;
-     }
-     return 0;
- }
  
- static int handle_pkt_tx(struct guest_info *core, struct virtio_vnet_state * vnet_brg) 
+ static int handle_pkt_kick(struct guest_info *core, struct virtio_vnet_state * vnet_state) 
  {
-     struct virtio_queue * q = &(vnet_brg->queue[XMIT_QUEUE]);
-     if (q->avail->index < q->last_avail_idx) {
-       q->idx_overflow = true;
-     }
-     q->last_avail_idx = q->avail->index;
+     struct virtio_queue * q = &(vnet_state->queue[XMIT_QUEUE]);
  
      PrintDebug("VNET Bridge Device: Handle TX\n");
  
-     while (q->cur_avail_idx < q->avail->index || 
-          (q->idx_overflow && q->cur_avail_idx < (q->avail->index + 65536))) {
-       struct vring_desc * buf_desc = NULL;
+     while (q->cur_avail_idx != q->avail->index) {
        uint16_t desc_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
+       struct vring_desc * pkt_desc = NULL;
+       struct vnet_virtio_pkt * virtio_pkt = NULL;
  
-       buf_desc = &(q->desc[desc_idx]);
+       pkt_desc = &(q->desc[desc_idx]);
  
-       PrintDebug("VNET Bridge: Handle TX buf_len: %d\n", buf_desc->length);
+       PrintDebug("VNET Bridge: Handle TX buf_len: %d\n", pkt_desc->length);
  
-       if (pkt_tx(core, vnet_brg, buf_desc) == -1) {
-               PrintError("Error handling nic operation\n");
-               return -1;
+       if (guest_pa_to_host_va(core, pkt_desc->addr_gpa, (addr_t *)&(virtio_pkt)) == -1) {
+           PrintError("Could not translate buffer address\n");
+           return -1;
        }
-        
+       //TODO:  SETUP VNET PACKET data structure
+       /*
+         if (v3_vnet_send_pkt(pkt, (void *)core) == -1) {
+           PrintError("Error sending packet to vnet\n");
+           return -1;
+       }       
+       */
        q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
-       q->used->ring[q->used->index % q->queue_size].length = buf_desc->length; // What do we set this to????
+       q->used->ring[q->used->index % q->queue_size].length = pkt_desc->length; // What do we set this to????
        q->used->index++;
  
-       int last_idx = q->cur_avail_idx;
-       q->cur_avail_idx ++;
-       if (q->cur_avail_idx < last_idx) {
-           q->idx_overflow = false;
-       }
+       q->cur_avail_idx++;
      }
  
      if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
-       v3_pci_raise_irq(vnet_brg->pci_bus, 0, vnet_brg->pci_dev);
-       vnet_brg->virtio_cfg.pci_isr = 0x1;
+       v3_pci_raise_irq(vnet_state->pci_bus, 0, vnet_state->pci_dev);
+       vnet_state->virtio_cfg.pci_isr = 0x1;
      }
  
  #ifdef CONFIG_VNET_PROFILE
      return 0;
  }
  
- static int vnetbrg_io_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * private_data) {
-     struct virtio_vnet_state * vnet_brg = (struct virtio_vnet_state *)private_data;
-     int port_idx = port % vnet_brg->io_range_size;
+ static int virtio_io_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * private_data) {
+     struct virtio_vnet_state * vnet_state = (struct virtio_vnet_state *)private_data;
+     int port_idx = port % vnet_state->io_range_size;
  
 -
      PrintDebug("VNET Bridge: VIRTIO VNET Write for port %d len=%d, value=%x\n", 
               port, length, *(uint32_t *)src);
      PrintDebug("VNET Bridge: port idx=%d\n", port_idx);
                PrintError("Illegal write length for guest features\n");
                return -1;
            }    
-           vnet_brg->virtio_cfg.guest_features = *(uint32_t *)src;
+           vnet_state->virtio_cfg.guest_features = *(uint32_t *)src;
  
            break;
        case VRING_PG_NUM_PORT:
                addr_t pfn = *(uint32_t *)src;
                addr_t page_addr = (pfn << VIRTIO_PAGE_SHIFT);
  
-               vnet_brg->cur_queue->pfn = pfn;
+               vnet_state->cur_queue->pfn = pfn;
                
-               vnet_brg->cur_queue->ring_desc_addr = page_addr ;
-               vnet_brg->cur_queue->ring_avail_addr = page_addr + (QUEUE_SIZE * sizeof(struct vring_desc));
-               vnet_brg->cur_queue->ring_used_addr = ( vnet_brg->cur_queue->ring_avail_addr + \
+               vnet_state->cur_queue->ring_desc_addr = page_addr ;
+               vnet_state->cur_queue->ring_avail_addr = page_addr + (QUEUE_SIZE * sizeof(struct vring_desc));
+               vnet_state->cur_queue->ring_used_addr = ( vnet_state->cur_queue->ring_avail_addr + \
                                                 sizeof(struct vring_avail)    + \
                                                 (QUEUE_SIZE * sizeof(uint16_t)));
                
                // round up to next page boundary.
-               vnet_brg->cur_queue->ring_used_addr = (vnet_brg->cur_queue->ring_used_addr + 0xfff) & ~0xfff;
+               vnet_state->cur_queue->ring_used_addr = (vnet_state->cur_queue->ring_used_addr + 0xfff) & ~0xfff;
  
-               if (guest_pa_to_host_va(core, vnet_brg->cur_queue->ring_desc_addr, (addr_t *)&(vnet_brg->cur_queue->desc)) == -1) {
+               if (guest_pa_to_host_va(core, vnet_state->cur_queue->ring_desc_addr, (addr_t *)&(vnet_state->cur_queue->desc)) == -1) {
                    PrintError("Could not translate ring descriptor address\n");
                    return -1;
                }
  
-               if (guest_pa_to_host_va(core, vnet_brg->cur_queue->ring_avail_addr, (addr_t *)&(vnet_brg->cur_queue->avail)) == -1) {
+               if (guest_pa_to_host_va(core, vnet_state->cur_queue->ring_avail_addr, (addr_t *)&(vnet_state->cur_queue->avail)) == -1) {
                    PrintError("Could not translate ring available address\n");
                    return -1;
                }
  
-               if (guest_pa_to_host_va(core, vnet_brg->cur_queue->ring_used_addr, (addr_t *)&(vnet_brg->cur_queue->used)) == -1) {
+               if (guest_pa_to_host_va(core, vnet_state->cur_queue->ring_used_addr, (addr_t *)&(vnet_state->cur_queue->used)) == -1) {
                    PrintError("Could not translate ring used address\n");
                    return -1;
                }
  
                PrintDebug("VNET Bridge: RingDesc_addr=%p, Avail_addr=%p, Used_addr=%p\n",
-                          (void *)(vnet_brg->cur_queue->ring_desc_addr),
-                          (void *)(vnet_brg->cur_queue->ring_avail_addr),
-                          (void *)(vnet_brg->cur_queue->ring_used_addr));
+                          (void *)(vnet_state->cur_queue->ring_desc_addr),
+                          (void *)(vnet_state->cur_queue->ring_avail_addr),
+                          (void *)(vnet_state->cur_queue->ring_used_addr));
  
                PrintDebug("VNET Bridge: RingDesc=%p, Avail=%p, Used=%p\n", 
-                          vnet_brg->cur_queue->desc, vnet_brg->cur_queue->avail, vnet_brg->cur_queue->used);
+                          vnet_state->cur_queue->desc, vnet_state->cur_queue->avail, vnet_state->cur_queue->used);
  
            } else {
                PrintError("Illegal write length for page frame number\n");
            }
            break;
        case VRING_Q_SEL_PORT:
-           vnet_brg->virtio_cfg.vring_queue_selector = *(uint16_t *)src;
+           vnet_state->virtio_cfg.vring_queue_selector = *(uint16_t *)src;
  
-           if (vnet_brg->virtio_cfg.vring_queue_selector > NUM_QUEUES) {
+           if (vnet_state->virtio_cfg.vring_queue_selector > NUM_QUEUES) {
                PrintError("VNET Bridge device has no qeueues. Selected %d\n", 
-                          vnet_brg->virtio_cfg.vring_queue_selector);
+                          vnet_state->virtio_cfg.vring_queue_selector);
                return -1;
            }
            
-           vnet_brg->cur_queue = &(vnet_brg->queue[vnet_brg->virtio_cfg.vring_queue_selector]);
+           vnet_state->cur_queue = &(vnet_state->queue[vnet_state->virtio_cfg.vring_queue_selector]);
  
            break;
        case VRING_Q_NOTIFY_PORT: {
            PrintDebug("VNET Bridge: Handling Kick\n");
  
            if (queue_idx == 0) {
-               if (handle_cmd_kick(core, vnet_brg) == -1) {
+               if (handle_cmd_kick(core, vnet_state) == -1) {
                    PrintError("Could not handle Virtio VNET Control command\n");
                    return -1;
                }
            } else if (queue_idx == 1) {
-               if (handle_pkt_tx(core, vnet_brg) == -1){
+               if (handle_pkt_kick(core, vnet_state) == -1){
                    PrintError("Could not handle Virtio VNET TX\n");
                    return -1;
                }
            break;
        }
        case VIRTIO_STATUS_PORT:
-           vnet_brg->virtio_cfg.status = *(uint8_t *)src;
+           vnet_state->virtio_cfg.status = *(uint8_t *)src;
  
-           if (vnet_brg->virtio_cfg.status == 0) {
+           if (vnet_state->virtio_cfg.status == 0) {
                PrintDebug("VNET Bridge: Resetting device\n");
-               vnetbrg_reset(vnet_brg);
+               virtio_reset(vnet_state);
            }
  
            break;
  
        case VIRTIO_ISR_PORT:
-           vnet_brg->virtio_cfg.pci_isr = *(uint8_t *)src;
+           vnet_state->virtio_cfg.pci_isr = *(uint8_t *)src;
            break;
        default:
            return -1;
  }
  
  
 -static int virtio_io_read(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * private_data) {
 +static int vnetbrg_io_read(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * private_data) {
  
      struct virtio_vnet_state * vnet_state = (struct virtio_vnet_state *)private_data;
      int port_idx = port % vnet_state->io_range_size;
      return length;
  }
  
- static int vnet_brg_input(struct v3_vm_info * vm, 
-                               struct v3_vnet_pkt * pkt, 
-                               void * private_data){
  
-     return vnet_brg_rx(pkt, private_data);
- }
  
  static struct v3_device_ops dev_ops = {
      .free = NULL,
  };
  
  
- static int vnet_brg_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
+ static int dev_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
      struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
-     struct virtio_vnet_state * vbrg_state = NULL;
+     struct virtio_vnet_state * vnet_state = NULL;
      struct pci_device * pci_dev = NULL;
      char * name = v3_cfg_val(cfg, "name");
  
        return -1;
      }
      
-     vbrg_state  = (struct virtio_vnet_state *)V3_Malloc(sizeof(struct virtio_vnet_state));
-     memset(vbrg_state, 0, sizeof(struct virtio_vnet_state));
+     vnet_state  = (struct virtio_vnet_state *)V3_Malloc(sizeof(struct virtio_vnet_state));
+     memset(vnet_state, 0, sizeof(struct virtio_vnet_state));
        
-     vbrg_state->vm = vm;
+     vnet_state->vm = vm;
  
-     struct vm_device * dev = v3_allocate_device(name, &dev_ops, vbrg_state);
+     struct vm_device * dev = v3_allocate_device(name, &dev_ops, vnet_state);
  
      if (v3_attach_device(vm, dev) == -1) {
        PrintError("Could not attach device %s\n", name);
        int i;
  
        // This gets the number of ports, rounded up to a power of 2
-       vbrg_state->io_range_size = 1; // must be a power of 2
+       vnet_state->io_range_size = 1; // must be a power of 2
  
        while (tmp_ports > 0) {
            tmp_ports >>= 1;
-           vbrg_state->io_range_size <<= 1;
+           vnet_state->io_range_size <<= 1;
        }
        
        // this is to account for any low order bits being set in num_ports
        // if there are none, then num_ports was already a power of 2 so we shift right to reset it
-       if ((num_ports & ((vbrg_state->io_range_size >> 1) - 1)) == 0) {
-           vbrg_state->io_range_size >>= 1;
+       if ((num_ports & ((vnet_state->io_range_size >> 1) - 1)) == 0) {
+           vnet_state->io_range_size >>= 1;
        }
  
        for (i = 0; i < 6; i++) {
  
        bars[0].type = PCI_BAR_IO;
        bars[0].default_base_port = -1;
-       bars[0].num_ports = vbrg_state->io_range_size;
-       bars[0].io_read = vnetbrg_io_read;
-       bars[0].io_write = vnetbrg_io_write;
-       bars[0].private_data = vbrg_state;
+       bars[0].num_ports = vnet_state->io_range_size;
+       bars[0].io_read = virtio_io_read;
+       bars[0].io_write = virtio_io_write;
+       bars[0].private_data = vnet_state;
  
        pci_dev = v3_pci_register_device(pci_bus, PCI_STD_DEVICE, 
                                         0, PCI_AUTO_DEV_NUM, 0,
                                         "LNX_VIRTIO_VNET", bars,
-                                        NULL, NULL, NULL, vbrg_state);
+                                        NULL, NULL, NULL, vnet_state);
  
        if (!pci_dev) {
            PrintError("Could not register PCI Device\n");
        pci_dev->config_header.max_latency = 1; // ?? (qemu does it...)
  
  
-       vbrg_state->pci_dev = pci_dev;
-       vbrg_state->pci_bus = pci_bus;
+       vnet_state->pci_dev = pci_dev;
+       vnet_state->pci_bus = pci_bus;
      }
  
-     vnetbrg_reset(vbrg_state);
+     virtio_reset(vnet_state);
  
-     v3_vnet_add_bridge(vm, vnet_brg_input, (void *)vbrg_state);
+     V3_Print("Registering Virtio device as vnet bridge\n");
+     v3_vnet_add_bridge(vm, vnet_pkt_input_cb, (void *)vnet_state);
  
      return 0;
  }
  
  
- device_register("LNX_VNET_BRG", vnet_brg_init)
+ device_register("LNX_VIRTIO_VNET", dev_init)
  
  struct vnet_nic_state {
      char mac[6];
--    struct guest_info * core;
++    struct v3_vm_info * vm;
      struct v3_dev_net_ops net_ops;
++    int vnet_dev_id;
  };
  
  #if 0
--//used when virtio_nic get a packet from guest and send it to the backend
++//Malloc/Free version of send
  static int vnet_send(uint8_t * buf, uint32_t len, void * private_data, struct vm_device *dest_dev){
      struct v3_vnet_pkt * pkt = NULL;
      struct guest_info *core  = (struct guest_info *)private_data; 
  //alternative way, no malloc/free
  static int vnet_send(uint8_t * buf, uint32_t len, void * private_data, struct vm_device *dest_dev){
      struct v3_vnet_pkt pkt;
--    struct guest_info *core  = (struct guest_info *)private_data; 
--
--#ifdef CONFIG_DEBUG_VNET_NIC
--    {
--      PrintDebug("Virtio VNET-NIC: send pkt size: %d\n", len);
--      v3_hexdump(buf, len, NULL, 0);
--    }
--#endif
++    struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
++    struct guest_info *core  = &(vnetnic->vm->cores[0]); 
  
  #ifdef CONFIG_VNET_PROFILE
      uint64_t start, end;
  
      pkt.size = len;
      pkt.src_type = LINK_INTERFACE;
--    pkt.src_id = 0;
++    pkt.src_id = vnetnic->vnet_dev_id;
      memcpy(pkt.data, buf, pkt.size);
  
++#ifdef CONFIG_DEBUG_VNET_NIC
++    {
++      PrintDebug("Virtio VNET-NIC: send pkt size: %d, pkt src_id: %d, src_type: %d\n", 
++                      len, pkt.src_id, pkt.src_type);
++      v3_hexdump(buf, len, NULL, 0);
++    }
++#endif
++
++
  #ifdef CONFIG_VNET_PROFILE
      rdtscll(end);
      core->vnet_times.time_copy_from_guest = end - core->vnet_times.virtio_handle_start;
@@@ -250,6 -250,6 +254,7 @@@ static int vnet_nic_init(struct v3_vm_i
  
      vnetnic->net_ops.send = vnet_send;
      memcpy(vnetnic->mac, mac, 6);
++    vnetnic->vm = vm;
        
      if (v3_dev_connect_net(vm, v3_cfg_val(frontend_cfg, "tag"), 
                           &(vnetnic->net_ops), frontend_cfg, vnetnic) == -1) {
      if ((vnet_dev_id = register_to_vnet(vm, vnetnic, name, vnetnic->mac)) == -1) {
        PrintError("Vnet-nic device %s (mac: %s) fails to registered to VNET\n", name, macstr);
      }
++    vnetnic->vnet_dev_id = vnet_dev_id;
  
      PrintDebug("Vnet-nic device %s (mac: %s, %ld) registered to VNET\n", name, macstr, *((ulong_t *)vnetnic->mac));
  
  
--//for temporary hack
--#if 0
++//for temporary hack for vnet bridge test
++#if 1
++    {
++      uchar_t zeromac[6] = {0,0,0,0,0,0};
++              
++      if(!strcmp(name, "vnet_nic")){
++          struct v3_vnet_route route;
++              
++          route.dst_id = vnet_dev_id;
++          route.dst_type = LINK_INTERFACE;
++          route.src_id = 0;
++          route.src_type = LINK_EDGE;
++          memcpy(route.dst_mac, zeromac, 6);
++          route.dst_mac_qual = MAC_ANY;
++          memcpy(route.src_mac, zeromac, 6);
++          route.src_mac_qual = MAC_ANY;  
++          v3_vnet_add_route(route);
++
++
++          route.dst_id = 0;
++          route.dst_type = LINK_EDGE;
++          route.src_id = vnet_dev_id;
++          route.src_type = LINK_INTERFACE;
++          memcpy(route.dst_mac, zeromac, 6);
++          route.dst_mac_qual = MAC_ANY;
++          memcpy(route.src_mac, zeromac, 6);
++          route.src_mac_qual = MAC_ANY;
++
++          v3_vnet_add_route(route);
++      }
++    }
++#endif
++#if 0 //temporay hacking for vnet virtio bridge
      {
        uchar_t tapmac[6] = {0x00,0x02,0x55,0x67,0x42,0x39}; //for Intel-VT test HW
        //uchar_t tapmac[6] = {0x6e,0xa8,0x75,0xf4,0x82,0x95};
            v3_vnet_add_route(route);
        }
      }
--
  #endif
  
      return 0;
@@@ -63,8 -63,8 +63,6 @@@ int host_pa_to_host_va(addr_t host_pa, 
      return 0;
  }
  
--
--
  int guest_pa_to_host_pa(struct guest_info * info, addr_t guest_pa, addr_t * host_pa) {
      struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info->vm_info, info->cpu_id, guest_pa);
  
@@@ -79,7 -79,7 +77,7 @@@
                   (void *)guest_pa, v3_shdw_region_type_to_str(shdw_reg->host_type));
        return -1;
      }
--    
++      
      *host_pa = v3_get_shadow_addr(shdw_reg, info->cpu_id, guest_pa);
  
      return 0;
@@@ -38,7 -38,7 +38,6 @@@
  
  
  
--
  /* At this point the GPRs are already copied into the guest_info state */
  int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_info) {
      struct vmx_data * vmx_info = (struct vmx_data *)(info->vmm_data);
        
        v3_print_vmcs();
      */
++#ifdef CONFIG_VNET_PROFILE
++    uint64_t start, end;
++    rdtscll(start);
++#endif
++
  #ifdef CONFIG_TELEMETRY
      if (info->vm_info->enable_telemetry) {
        v3_telemetry_start_exit(info);
      }
  #endif
  
++#ifdef CONFIG_VNET_PROFILE
++    rdtscll(end);
++    info->vnet_times.total_exit_time = end - start;
++    if(info->vnet_times.print) 
++      PrintError("Vnet_profiling: total_exit_time: %ld, total_handle_time: %ld memcpy_time: %ld  copy_from_guest: %ld copy_to_guest: %ld malloc_free: %ld, route_lookup: %ld\n", 
++                    (long)info->vnet_times.total_exit_time,
++                       (long)info->vnet_times.total_handle_time,
++                       (long)info->vnet_times.memcpy_time,
++                       (long)info->vnet_times.time_copy_from_guest,
++                       (long)info->vnet_times.time_copy_to_guest,
++                       (long)info->vnet_times.time_mallocfree,
++                       (long)info->vnet_times.time_route_lookup);
++
++    info->vnet_times.print = false;
++#endif
++
++
      return 0;
  }
  
@@@ -3,12 -3,12 +3,12 @@@
  <vm class="PC"> 
  
        <!-- Memory in MB -->
--      <memory>256</memory> 
++      <memory>512</memory> 
  
        <!-- Basic VMM system flags -->
        <telemetry>enable</telemetry>
        <paging mode="VTLB" />
--      <schedule_hz>100</schedule_hz>
++      <schedule_hz>1000</schedule_hz>
  
        <cores count="1"><core /></cores>
  
@@@ -29,7 -29,7 +29,7 @@@
        <!-- This is where you add disk images -->
        <files>
                <!-- The file 'id' is used as a reference for other configuration components -->
--              <file id="boot-cd" filename="/home/ktpedre/google_code/smp_guest/kitten_guest/arch/x86_64/boot/image.iso" />
++              <file id="boot-cd" filename="image.iso" />
                <!--<file id="harddisk" filename="firefox.img" />-->
        </files>
  
                        <bus>pci0</bus>
                        <controller>southbridge</controller>
                </device>
++                 
++                <device id="LNX_VIRTIO_NIC" name="net_virtio0">
++                        <bus>pci0</bus>
++                </device>
++
++               <device id="LNX_VIRTIO_NIC" name="net_virtio1">
++                        <bus>pci0</bus>
++                </device>
++
++                <device id="LNX_VIRTIO_NIC" name="net_virtio2">
++                        <bus>pci0</bus>
++                </device>
++
++               <device id="PCI_PASSTHROUGH" name="e1000">
++                        <bus>pci0</bus>
++                        <vendor_id>0x8086</vendor_id>
++                        <device_id>0x100e</device_id>
++                        <irq>59</irq>
++                </device>
++
  
  <!--
                <device id="LNX_VIRTIO_SYM" name="sym_pci">
                        </frontend>
                </device>
  
++              <device id="VNET_NIC", name="vnet_nic0">
++                      <frontend tag="net_virtio0">
++                              <mac>10:20:30:40:50:60</mac>
++                      </frontend>
++              </device>
++
++              <device id="VNET_NIC", name="vnet_nic1">
++                        <frontend tag="net_virtio1">
++                                       <mac>10:20:30:40:50:61</mac>
++                        </frontend>
++                </device>
++
++                <device id="VNET_NIC", name="vnet_nic2">
++                        <frontend tag="net_virtio2">
++                                <mac>10:20:30:40:50:62</mac>
++                        </frontend>
++                </device>
++
  <!---
                <device id="SYM_SWAP" name="sym swap">
                        <frontend tag="blk_virtio" />
                        <size>150</size>
                </device>
---->
--
--
  
                <device id="RAMDISK" name="HD0">
                        <file>harddisk</file>
                        <frontend tag="blk_virtio" />
                </device>
--
++-->
  
                <device id="NVRAM" name="nvram">
                        <storage>ide</storage>