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.


add the virtual console input as a host event
Lei Xia [Wed, 10 Nov 2010 03:38:41 +0000 (21:38 -0600)]
clean VNET code

Kconfig
palacios/include/palacios/vmm_host_events.h
palacios/include/palacios/vmm_vnet.h
palacios/src/devices/Makefile
palacios/src/devices/lnx_virtio_vnet.c
palacios/src/devices/lnx_vnet_brg.c
palacios/src/palacios/vmm_host_events.c
palacios/src/palacios/vmm_vnet.c

diff --git a/Kconfig b/Kconfig
index 0910a5f..bb241ee 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -182,6 +182,20 @@ config DEBUG_LINUX_VIRTIO_VNET
         help
           Enable debugging for the VNET Virtio Device
 
+config LINUX_VNET_BRIDGE
+        bool "Enable VNET Bridge for Linux host"
+        default n
+        depends on PCI && EXPERIMENTAL && VNET && LINUX
+        help
+          Enable the VNET Bridge for Linux host
+
+config DEBUG_LINUX_VNET_BRIDGE
+        bool "VNET Host Linux Bridge Debug"
+        default n
+        depends on LINUX_VNET_BRIDGE && DEBUG_ON && LINUX
+        help
+          Enable debugging for the VNET Host Linux Bridge
+
 endmenu
 
 
index 7539d6d..7a462b7 100644 (file)
@@ -34,6 +34,11 @@ struct v3_timer_event {
     unsigned int period_us;
 };
 
+struct v3_console_event {
+    unsigned char data[128];
+    unsigned int len;
+};
+
 #ifdef __V3VEE__
 
 #include <palacios/vmm_list.h>
@@ -42,13 +47,15 @@ struct v3_vm_info;
 
 typedef enum {HOST_KEYBOARD_EVT, 
              HOST_MOUSE_EVT, 
-             HOST_TIMER_EVT} v3_host_evt_type_t;
+             HOST_TIMER_EVT,
+             HOST_CONSLE_EVT} v3_host_evt_type_t;
 
 
 union v3_host_event_handler {
     int (*keyboard_handler)(struct v3_vm_info * vm, struct v3_keyboard_event * evt, void * priv_data);
     int (*mouse_handler)(struct v3_vm_info * vm, struct v3_mouse_event * evt, void * priv_data);
     int (*timer_handler)(struct v3_vm_info * vm, struct v3_timer_event * evt, void * priv_data);
+    int (*console_handler)(struct v3_vm_info * vm, struct v3_console_event * evt, void * priv_data);
 };
 
 
@@ -64,6 +71,7 @@ struct v3_host_events {
     struct list_head keyboard_events;
     struct list_head mouse_events;
     struct list_head timer_events;
+    struct list_head console_events;
 };
 
 
@@ -84,6 +92,7 @@ int v3_hook_host_event(struct v3_vm_info * vm,
 int v3_deliver_keyboard_event(struct v3_vm_info * vm, struct v3_keyboard_event * evt);
 int v3_deliver_mouse_event(struct v3_vm_info * vm, struct v3_mouse_event * evt);
 int v3_deliver_timer_event(struct v3_vm_info * vm, struct v3_timer_event * evt);
+int v3_deliver_console_event(struct v3_vm_info * vm, struct v3_console_event * evt);
 
 
 
index 05a6235..d990880 100644 (file)
@@ -70,7 +70,7 @@ struct v3_vnet_pkt {
            uint8_t src_type;
            uint32_t src_id;
            uint8_t header[ETHERNET_HEADER_LEN];
-           uint8_t *data;
+           uint8_t * data;
        } __attribute__((packed));
     } __attribute__((packed));
 } __attribute__((packed));
@@ -106,8 +106,10 @@ struct v3_vnet_dev_xcall_args{
 };
 
 struct v3_vnet_dev_ops {
-    int (*input)(struct v3_vm_info * vm, struct v3_vnet_pkt * pkt, void * dev_data);
-    void (*poll) (struct v3_vm_info *vm, void *dev_data);
+    int (*input)(struct v3_vm_info * vm, 
+               struct v3_vnet_pkt * pkt, 
+               void * dev_data);
+    void (*poll) (struct v3_vm_info * vm, void * dev_data);
     void (*poll_xcall)(void *arg);
 
     void (*start_tx)(void * dev_data);
@@ -115,9 +117,12 @@ struct v3_vnet_dev_ops {
 };
 
 struct v3_vnet_bridge_ops {
-    int (*input)(struct v3_vm_info * vm, struct v3_vnet_pkt pkt[], uint16_t pkt_num, void * private_data);
-    int (*xcall_input)(void *data);
-    void (*polling_pkt)(struct v3_vm_info * vm,  void *private_data);
+    int (*input)(struct v3_vm_info * vm, 
+               struct v3_vnet_pkt * pkt,
+               void * private_data);
+    int (*xcall_input)(void * data);
+    void (*polling_pkt)(struct v3_vm_info * vm,  
+               void * private_data);
 };
        
 
index 88356e1..e856045 100644 (file)
@@ -38,3 +38,4 @@ obj-$(CONFIG_PASSTHROUGH_PCI) += pci_passthrough.o
 
 obj-$(CONFIG_SYMMOD) += lnx_virtio_symmod.o
 obj-$(CONFIG_CHAR_STREAM) += char_stream.o
+obj-$(CONFIG_LINUX_VNET_BRIDGE) += lnx_vnet_brg.o
index 435df48..c35250d 100644 (file)
@@ -222,16 +222,12 @@ static int handle_cmd_kick(struct guest_info * core, struct virtio_vnet_state *
 }
 
 
-static int vnet_pkt_input_cb(struct v3_vm_info * vm,  struct v3_vnet_pkt vnet_pkts[], uint16_t pkt_num, void * private_data){
+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;
     uint16_t sent;
-    struct v3_vnet_pkt *pkt;
-
-    if(pkt_num <= 0)
-       return 0;
 
     flags = v3_lock_irqsave(vnet_state->lock);
        
@@ -240,45 +236,33 @@ static int vnet_pkt_input_cb(struct v3_vm_info * vm,  struct v3_vnet_pkt vnet_pk
        goto exit;
     }
 
-    PrintDebug("VNET Bridge: RX: running on cpu: %d, num of pkts: %d\n", V3_Get_CPU(), pkt_num);
-
-    for(sent = 0; sent < pkt_num; sent ++) {
-       pkt = &vnet_pkts[sent];
-       vnet_state->pkt_recv ++;
-
-       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_bridge_pkt * virtio_pkt = 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_bridge_pkt * virtio_pkt = NULL;
 
-           pkt_desc = &(q->desc[pkt_idx]);
-           PrintDebug("VNET Bridge RX: buffer desc len: %d\n", pkt_desc->length);
+       pkt_desc = &(q->desc[pkt_idx]);
+       PrintDebug("VNET Bridge RX: buffer desc len: %d\n", pkt_desc->length);
 
-           if (v3_gpa_to_hva(&(vm->cores[0]), pkt_desc->addr_gpa, (addr_t *)&(virtio_pkt)) == -1) {
-               PrintError("Could not translate buffer address\n");
-               goto exit;
-           }
+       if (v3_gpa_to_hva(&(vm->cores[0]), pkt_desc->addr_gpa, (addr_t *)&(virtio_pkt)) == -1) {
+           PrintError("Could not translate buffer address\n");
+           goto exit;
+       }
 
-           PrintDebug("VNET Bridge: RX: pkt sent to guest pkt size: %d, dst link: %d\n", pkt->size, pkt->dst_id);
+       PrintDebug("VNET Bridge: RX: pkt sent to guest pkt size: %d, dst link: %d\n", pkt->size, pkt->dst_id);
 
-           // 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);
+       // 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 = sizeof(struct vnet_bridge_pkt); 
-
-           q->used->index++;
-           q->cur_avail_idx++;
-       } else {
-           vnet_state->pkt_drop ++;
-           //v3_vnet_disable_bridge();
-       }
-    }
+       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 = sizeof(struct vnet_bridge_pkt); 
 
-    if(sent == 0){
-       goto exit;
+       q->used->index++;
+       q->cur_avail_idx++;
+    } else {
+       vnet_state->pkt_drop ++;
     }
 
     if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
@@ -288,19 +272,7 @@ static int vnet_pkt_input_cb(struct v3_vm_info * vm,  struct v3_vnet_pkt vnet_pk
     }
 
     ret_val = 0;
-
        
-#ifdef CONFIG_VNET_PROFILE
-    if (vnet_state->pkt_recv % 20000 == 0)
-       PrintError("Vnet Bridge: sent: %ld, rxed: %ld, dropped: %ld, total exit: %ld, tx exit: %ld, rx exit: %ld\n",
-                       vnet_state->pkt_sent,
-                       vnet_state->pkt_recv,
-                       vnet_state->pkt_drop, 
-                       vnet_state->total_exit,
-                       vnet_state->tx_exit,
-                       vnet_state->rx_exit);
-#endif
-
 exit:
 
     v3_unlock_irqrestore(vnet_state->lock, flags);
@@ -310,8 +282,13 @@ exit:
 
 static int vnet_pkt_input_xcall(void *data){
     struct v3_vnet_bridge_xcall_args *args = (struct v3_vnet_bridge_xcall_args *)data;
+    int i = 0;
+
+    for(i = 0; i < args->pkt_num; i++) {
+       vnet_pkt_input_cb(args->vm, args->vnet_pkts[i], args->private_data);
+    }
        
-    return vnet_pkt_input_cb(args->vm, args->vnet_pkts, args->pkt_num, args->private_data);
+    return 0;
 }
 
 static int handle_pkt_kick(struct guest_info *core, struct virtio_vnet_state * vnet_state) 
@@ -366,20 +343,7 @@ static int handle_pkt_kick(struct guest_info *core, struct virtio_vnet_state * v
            v3_pci_raise_irq(vnet_state->pci_bus, 0, vnet_state->pci_dev);
            vnet_state->virtio_cfg.pci_isr = 0x1;
     }
-
-    //PrintError("Virtio VNET: polling %d pkts\n", recvd);
        
-#ifdef CONFIG_VNET_PROFILE
-    if (vnet_state->pkt_sent % 20000 == 0)
-       PrintError("Vnet Bridge: sent: %ld, rxed: %ld, dropped: %ld, total exit: %ld, tx exit: %ld, rx exit: %ld\n",
-                       vnet_state->pkt_sent,
-                       vnet_state->pkt_recv,
-                       vnet_state->pkt_drop, 
-                       vnet_state->total_exit,
-                       vnet_state->tx_exit,
-                       vnet_state->rx_exit);
-#endif
-
     return 0;
 }
 
index 366dc46..c4f7272 100644 (file)
@@ -41,6 +41,7 @@ struct vnet_link {
     
     int socket;
     sock_type_t type;
+
     int link_idx;
 
     struct list_head node;
@@ -48,22 +49,17 @@ struct vnet_link {
 
 struct vnet_brg_state {
     uint32_t num_links; 
-
     struct list_head link_list;
 
     int serv_sock;
     sock_type_t serv_sock_type;
     int serv_port;
-    
-    /* The thread recving pkts from sockets. */
-    int serv_thread;
 
     v3_lock_t lock;
 
     unsigned long pkt_sent, pkt_recv, pkt_drop;
 };
 
-static struct vnet_brg_state lnxbrg_state;
 
 static int vnet_lnxbrg_reset(struct vnet_brg_state * state) {
     memset(state, 0, sizeof(struct vnet_brg_state));
@@ -127,10 +123,10 @@ udp_recv(int sockid, uint32_t * src_ip,
 
 
 static int 
-brg_send(struct vnet_brg_state * state,
-                       struct v3_vm_info * vm,  
+brg_send(      struct v3_vm_info * vm,  
                        struct v3_vnet_pkt * vnet_pkt, 
                        void * private_data){
+    struct vnet_brg_state * state = (struct vnet_brg_state *)private_data;
     struct vnet_link * link = NULL;
        
     #ifdef CONFIG_DEBUG_VNET_LNX_BRIGE
@@ -143,11 +139,9 @@ brg_send(struct vnet_brg_state * state,
     #endif
 
     state->pkt_recv ++;
-    link = link_by_idx(vnet_pkt->dst_id);
+    link = link_by_idx(state, vnet_pkt->dst_id);
     if (link != NULL) {
-       if(link->type == SOCK_TCP){
-               
-       }else if(link->type == SOCK_UDP){
+       if(link->type == SOCK_UDP){
            udp_send(link->socket, 0, 0, vnet_pkt->data, vnet_pkt->size);
            state->pkt_sent ++;
        }else {
@@ -200,7 +194,7 @@ static int vnet_server(void * arg) {
            continue;
        }
 
-       link = link_by_ip(ip);
+       link = link_by_ip(state, ip);
        if (link != NULL) {
            pkt.src_id= link->link_idx;
        }
@@ -243,7 +237,7 @@ static int vnet_lnxbrg_init() {
 
     v3_vnet_add_bridge(NULL, &brg_ops, state);
 
-    init_serv();
+    init_serv(state);
     V3_CREATE_THREAD(vnet_server, state, "VNET_LNX_BRIDGE");
 
     PrintDebug("VNET Linux Bridge initiated\n");
index f872149..ec54c65 100644 (file)
@@ -60,6 +60,9 @@ int v3_hook_host_event(struct v3_vm_info * vm,
        case HOST_TIMER_EVT:
            list_add(&(hook->link), &(host_evts->timer_events));
            break;
+       case HOST_CONSLE_EVT:
+           list_add(&(hook->link), &(host_evts->console_events));
+           break;
     }
 
     return 0;
@@ -139,3 +142,28 @@ int v3_deliver_timer_event(struct v3_vm_info * vm,
 
     return 0;
 }
+
+int v3_deliver_console_event(struct v3_vm_info * vm, 
+                          struct v3_console_event * evt) {
+    struct v3_host_events * host_evts = NULL;
+    struct v3_host_event_hook * hook = NULL;
+
+    if (vm == NULL) {
+       vm = v3_get_foreground_vm();
+    }
+
+    host_evts = &(vm->host_event_hooks);
+
+    if (vm->run_state != VM_RUNNING) {
+       return -1;
+    }
+
+    list_for_each_entry(hook, &(host_evts->console_events), link) {
+       if (hook->cb.console_handler(vm, evt, hook->private_data) == -1) {
+           return -1;
+       }
+    }
+
+    return 0;
+}
+
index 1ec015e..e263735 100644 (file)
@@ -450,7 +450,7 @@ static int send_to_bridge(struct v3_vnet_pkt * pkt){
        return -1;
     }
 
-    return bridge->brg_ops.input(bridge->vm, pkt, 1, bridge->private_data);
+    return bridge->brg_ops.input(bridge->vm, pkt, bridge->private_data);
 }