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.


Update on VNET-NIC device, and fix vnet & virtio net
[palacios.git] / palacios / src / devices / lnx_virtio_nic.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Lei Xia <lxia@northwestern.edu>
11  * Copyright (c) 2008, Cui Zheng <cuizheng@cs.unm.edu>
12  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
13  * All rights reserved.
14  *
15  * Author: Lei Xia <lxia@northwestern.edu>
16  *             Cui Zheng <cuizheng@cs.unm.edu>
17  *               
18  *
19  * This is free software.  You are permitted to use,
20  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
21  */
22  
23 #include <palacios/vmm.h>
24 #include <palacios/vmm_dev_mgr.h>
25 #include <devices/lnx_virtio_pci.h>
26 #include <palacios/vm_guest_mem.h>
27 #include <palacios/vmm_sprintf.h>
28 #include <palacios/vmm_vnet.h>
29 #include <palacios/vmm_lock.h>
30
31 #include <devices/pci.h>
32
33
34 #ifndef CONFIG_DEBUG_VIRTIO_NET
35 #undef PrintDebug
36 #define PrintDebug(fmt, args...)
37 #endif
38
39 #define VIRTIO_NIC_PROFILE
40
41 #define VIRTIO_NET_S_LINK_UP    1       /* Link is up */
42 #define VIRTIO_NET_MAX_BUFSIZE (sizeof(struct virtio_net_hdr) + (64 << 10))
43
44 struct virtio_net_hdr {
45         uint8_t flags;
46
47 #define VIRTIO_NET_HDR_GSO_NONE         0       /* Not a GSO frame */
48         uint8_t gso_type;
49         uint16_t hdr_len;               /* Ethernet + IP + tcp/udp hdrs */
50         uint16_t gso_size;              /* Bytes to append to hdr_len per frame */
51         uint16_t csum_start;    /* Position to start checksumming from */
52         uint16_t csum_offset;   /* Offset after that to place checksum */
53 }__attribute__((packed));
54
55         
56 #define QUEUE_SIZE 1024
57 #define CTRL_QUEUE_SIZE 64
58 #define ETH_ALEN 6
59
60 struct virtio_net_config
61 {
62     uint8_t mac[ETH_ALEN]; //VIRTIO_NET_F_MAC
63     uint16_t status;
64 } __attribute__((packed));
65
66 struct virtio_dev_state {
67     struct vm_device * pci_bus;
68     struct list_head dev_list;
69     struct guest_info *vm;
70 };
71
72 struct virtio_net_state {
73     struct virtio_net_config net_cfg;
74     struct virtio_config virtio_cfg;
75
76     struct vm_device * dev;
77     struct pci_device * pci_dev; 
78     int io_range_size;
79     
80     struct virtio_queue rx_vq;   //index 0, rvq in Linux virtio driver, handle packet to guest
81     struct virtio_queue tx_vq;   //index 1, svq in Linux virtio driver, handle packet from guest
82     struct virtio_queue ctrl_vq; //index 2, ctrol info from guest
83
84     ulong_t pkt_sent, pkt_recv, pkt_drop;
85
86     struct v3_dev_net_ops * net_ops;
87
88     void * backend_data;
89     struct virtio_dev_state * virtio_dev;
90     struct list_head dev_link;
91 };
92
93 static int virtio_free(struct vm_device * dev) 
94 {
95         
96     return -1;
97 }
98
99 static int virtio_init_state(struct virtio_net_state * virtio) 
100 {
101     virtio->rx_vq.ring_desc_addr = 0;
102     virtio->rx_vq.ring_avail_addr = 0;
103     virtio->rx_vq.ring_used_addr = 0;
104     virtio->rx_vq.pfn = 0;
105     virtio->rx_vq.cur_avail_idx = 0;
106
107     virtio->tx_vq.ring_desc_addr = 0;
108     virtio->tx_vq.ring_avail_addr = 0;
109     virtio->tx_vq.ring_used_addr = 0;
110     virtio->tx_vq.pfn = 0;
111     virtio->tx_vq.cur_avail_idx = 0;
112
113     virtio->ctrl_vq.ring_desc_addr = 0;
114     virtio->ctrl_vq.ring_avail_addr = 0;
115     virtio->ctrl_vq.ring_used_addr = 0;
116     virtio->ctrl_vq.pfn = 0;
117     virtio->ctrl_vq.cur_avail_idx = 0;
118
119     virtio->virtio_cfg.host_features = 0;
120     //virtio->virtio_cfg.status = VIRTIO_NET_S_LINK_UP;
121     virtio->virtio_cfg.pci_isr = 0;
122
123     virtio->pkt_sent = virtio->pkt_recv = virtio->pkt_drop = 0;
124
125     return 0;
126 }
127
128 static int pkt_tx(struct virtio_net_state * virtio, struct vring_desc * buf_desc) 
129 {
130     uint8_t * buf = NULL;
131     uint32_t len = buf_desc->length;
132
133     PrintDebug("Virtio NIC: Handling Virtio Write, net_state: %p\n", virtio);
134
135     if (guest_pa_to_host_va(virtio->virtio_dev->vm, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) {
136         PrintError("Could not translate buffer address\n");
137         return -1;
138     }
139
140     if (virtio->net_ops->send(buf, len, (void *)virtio, NULL) == -1) {
141         return -1;
142     }
143
144     return 0;
145 }
146
147 static int build_receive_header(struct virtio_net_hdr * hdr, const void * buf, int raw) {
148     hdr->flags = 0;
149
150     if (!raw) {
151         memcpy(hdr, buf, sizeof(struct virtio_net_hdr));
152     } else {
153         memset(hdr, 0, sizeof(struct virtio_net_hdr));
154     }
155
156     return 0;
157 }
158
159 static int copy_data_to_desc(struct virtio_net_state * virtio_state, struct vring_desc * desc, uchar_t * buf, uint_t buf_len) 
160 {
161     uint32_t len;
162     uint8_t * desc_buf = NULL;
163
164     if (guest_pa_to_host_va(virtio_state->virtio_dev->vm, desc->addr_gpa, (addr_t *)&(desc_buf)) == -1) {
165         PrintError("Could not translate buffer address\n");
166         return -1;
167     }
168     len = (desc->length < buf_len)?desc->length:buf_len;
169     memcpy(desc_buf, buf, len);
170
171     return len;
172 }
173
174 //send data to guest
175 int send_pkt_to_guest(struct virtio_net_state * virtio, uchar_t * buf, uint_t size, int raw, void * private_data) 
176 {
177     struct virtio_queue * q = &(virtio->rx_vq);
178     struct virtio_net_hdr hdr;
179     uint32_t hdr_len = sizeof(struct virtio_net_hdr);
180     uint32_t data_len = size;
181     uint32_t offset = 0;
182         
183     PrintDebug("VIRTIO NIC:  sending packet to virtio nic %p, size:%d", virtio, size);
184
185     virtio->pkt_recv ++;
186     if (!raw) {
187         data_len -= hdr_len;
188     }
189
190     build_receive_header(&hdr, buf, 1);
191
192     if (q->ring_avail_addr == 0) {
193         PrintError("Queue is not set\n");
194         return -1;
195     }
196
197     if (q->last_avail_idx > q->avail->index)
198         q->idx_overflow = true;
199     q->last_avail_idx = q->avail->index;
200
201     if (q->cur_avail_idx < q->avail->index || (q->idx_overflow && q->cur_avail_idx < q->avail->index+65536)){
202         addr_t hdr_addr = 0;
203         uint16_t hdr_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
204         uint16_t buf_idx = 0;
205         struct vring_desc * hdr_desc = NULL;
206
207         hdr_desc = &(q->desc[hdr_idx]);
208         if (guest_pa_to_host_va(virtio->virtio_dev->vm, hdr_desc->addr_gpa, &(hdr_addr)) == -1) {
209             PrintError("Could not translate receive buffer address\n");
210             return -1;
211         }
212
213         memcpy((void *)hdr_addr, &hdr, sizeof(struct virtio_net_hdr));
214         if (offset >= data_len) {
215             hdr_desc->flags &= ~VIRTIO_NEXT_FLAG;
216         }
217
218         for (buf_idx = hdr_desc->next; offset < data_len; buf_idx = q->desc[hdr_idx].next) {
219             struct vring_desc * buf_desc = &(q->desc[buf_idx]);
220             uint32_t len = 0;
221
222             len = copy_data_to_desc(virtio, buf_desc, buf + offset, data_len - offset);     
223             offset += len;
224             if (offset < data_len) {
225                 buf_desc->flags = VIRTIO_NEXT_FLAG;             
226             }
227             buf_desc->length = len;
228         }
229         
230         q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
231         q->used->ring[q->used->index % q->queue_size].length = data_len + hdr_len; // This should be the total length of data sent to guest (header+pkt_data)
232         q->used->index++;
233
234         int last_idx = q->cur_avail_idx;
235         q->cur_avail_idx++;
236         if (q->cur_avail_idx < last_idx)
237             q->idx_overflow = false;
238     } else {
239         virtio->pkt_drop++;
240
241 #ifdef VIRTIO_NIC_PROFILE
242         PrintError("Virtio NIC: %p, one pkt dropped receieved: %ld, dropped: %ld, sent: %ld curidx: %d, avaiIdx: %d\n", 
243                 virtio, virtio->pkt_recv, virtio->pkt_drop, virtio->pkt_sent, q->cur_avail_idx, q->avail->index);
244 #endif
245     }
246
247     if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
248         PrintDebug("Raising IRQ %d\n",  virtio->pci_dev->config_header.intr_line);
249         v3_pci_raise_irq(virtio->virtio_dev->pci_bus, 0, virtio->pci_dev);
250         virtio->virtio_cfg.pci_isr = 0x1;
251     }
252
253 #ifdef VIRTIO_NIC_PROFILE
254     if ((virtio->pkt_recv % 10000) == 0){
255         PrintError("Virtio NIC: %p, receieved: %ld, dropped: %ld, sent: %ld\n", 
256                 virtio, virtio->pkt_recv, virtio->pkt_drop, virtio->pkt_sent);
257     }
258 #endif
259
260     
261     return offset;
262 }
263
264 int virtio_dev_send(struct v3_vm_info *info,
265                                    uchar_t * buf,
266                                    uint32_t size,
267                                    void *private_data) {
268     struct virtio_net_state *virtio_state = (struct virtio_net_state *)private_data;
269
270     return send_pkt_to_guest(virtio_state, buf, size, 1, NULL);
271 }
272
273 static int get_desc_count(struct virtio_queue * q, int index) {
274     struct vring_desc * tmp_desc = &(q->desc[index]);
275     int cnt = 1;
276     
277     while (tmp_desc->flags & VIRTIO_NEXT_FLAG) {
278         tmp_desc = &(q->desc[tmp_desc->next]);
279         cnt++;
280     }
281
282     return cnt;
283 }
284
285 static int handle_ctrl(struct virtio_net_state * dev) {
286     return 0;
287 }
288
289 static int handle_pkt_tx(struct virtio_net_state * virtio_state) 
290 {
291     struct virtio_queue * q = &(virtio_state->tx_vq);
292     struct virtio_net_hdr * hdr = NULL;
293
294     if (q->avail->index < q->last_avail_idx)
295         q->idx_overflow = true;
296     q->last_avail_idx = q->avail->index;
297
298     while (q->cur_avail_idx < q->avail->index || 
299                  (q->idx_overflow && q->cur_avail_idx < (q->avail->index + 65536))) {
300         struct vring_desc * hdr_desc = NULL;
301         addr_t hdr_addr = 0;
302         uint16_t desc_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
303         int desc_cnt = get_desc_count(q, desc_idx);
304         uint32_t req_len = 0;
305         int i = 0;
306
307         hdr_desc = &(q->desc[desc_idx]);
308         if (guest_pa_to_host_va(virtio_state->virtio_dev->vm, hdr_desc->addr_gpa, &(hdr_addr)) == -1) {
309             PrintError("Could not translate block header address\n");
310             return -1;
311         }
312
313         hdr = (struct virtio_net_hdr*)hdr_addr;
314         desc_idx = hdr_desc->next;
315         
316         for (i = 0; i < desc_cnt - 1; i++) {    
317             struct vring_desc * buf_desc = &(q->desc[desc_idx]);
318             if (pkt_tx(virtio_state, buf_desc) == -1) {
319                 PrintError("Error handling nic operation\n");
320                 return -1;
321             }
322
323             req_len += buf_desc->length;
324             desc_idx = buf_desc->next;
325         }
326         virtio_state->pkt_sent ++;
327
328         q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
329         q->used->ring[q->used->index % q->queue_size].length = req_len; // What do we set this to????
330         q->used->index++;
331
332         int last_idx = q->cur_avail_idx;
333         q->cur_avail_idx ++;
334         if (q->cur_avail_idx < last_idx)
335             q->idx_overflow = false;
336     }
337
338     if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
339         v3_pci_raise_irq(virtio_state->virtio_dev->pci_bus, 0, virtio_state->pci_dev);
340         virtio_state->virtio_cfg.pci_isr = 0x1;
341     }
342
343 #ifdef VIRTIO_NIC_PROFILE
344     if(virtio_state->pkt_sent % 10000 == 0)
345         PrintError("Virtio NIC: %p, pkt_sent: %ld\n", virtio_state, virtio_state->pkt_sent);
346 #endif  
347
348     return 0;
349 }
350
351 static int virtio_setup_queue(struct virtio_net_state * virtio_state, struct virtio_queue * queue, addr_t pfn, addr_t page_addr) {
352     queue->pfn = pfn;
353                 
354     queue->ring_desc_addr = page_addr;
355     queue->ring_avail_addr = page_addr + (queue->queue_size * sizeof(struct vring_desc));
356     queue->ring_used_addr = ((queue->ring_avail_addr) + 
357                              (sizeof(struct vring_avail)) + 
358                              (queue->queue_size * sizeof(uint16_t)));
359                 
360     // round up to next page boundary.
361     queue->ring_used_addr = (queue->ring_used_addr + 0xfff) & ~0xfff;
362     if (guest_pa_to_host_va(virtio_state->virtio_dev->vm, queue->ring_desc_addr, (addr_t *)&(queue->desc)) == -1) {
363         PrintError("Could not translate ring descriptor address\n");
364          return -1;
365     }
366  
367     if (guest_pa_to_host_va(virtio_state->virtio_dev->vm, queue->ring_avail_addr, (addr_t *)&(queue->avail)) == -1) {
368         PrintError("Could not translate ring available address\n");
369         return -1;
370     }
371
372     if (guest_pa_to_host_va(virtio_state->virtio_dev->vm, queue->ring_used_addr, (addr_t *)&(queue->used)) == -1) {
373         PrintError("Could not translate ring used address\n");
374         return -1;
375     }
376
377     PrintDebug("RingDesc_addr=%p, Avail_addr=%p, Used_addr=%p\n",
378                (void *)(queue->ring_desc_addr),
379                (void *)(queue->ring_avail_addr),
380                (void *)(queue->ring_used_addr));
381     
382     PrintDebug("RingDesc=%p, Avail=%p, Used=%p\n", 
383                queue->desc, queue->avail, queue->used);
384     
385     return 0;
386 }
387
388 static int virtio_io_write(struct guest_info *core, uint16_t port, void * src, uint_t length, void * private_data) 
389 {
390     struct virtio_net_state * virtio = (struct virtio_net_state *)private_data;
391     int port_idx = port % virtio->io_range_size;
392
393     PrintDebug("VIRTIO NIC %p Write for port %d (index=%d) len=%d, value=%x\n", private_data,
394                port, port_idx,  length, *(uint32_t *)src);
395
396     switch (port_idx) {
397         case GUEST_FEATURES_PORT:
398             if (length != 4) {
399                 PrintError("Illegal write length for guest features\n");
400                 return -1;
401             }       
402             virtio->virtio_cfg.guest_features = *(uint32_t *)src;
403             PrintDebug("Setting Guest Features to %x\n", virtio->virtio_cfg.guest_features);
404             break;
405                 
406         case VRING_PG_NUM_PORT:
407             if (length != 4) {
408                 PrintError("Illegal write length for page frame number\n");
409                 return -1;
410             }
411             addr_t pfn = *(uint32_t *)src;
412             addr_t page_addr = (pfn << VIRTIO_PAGE_SHIFT);
413             uint16_t queue_idx = virtio->virtio_cfg.vring_queue_selector;
414             switch (queue_idx) {
415                 case 0:
416                     virtio_setup_queue(virtio, &virtio->rx_vq, pfn, page_addr);
417                     break;
418                 case 1:
419                     virtio_setup_queue(virtio, &virtio->tx_vq, pfn, page_addr);
420                     break;
421                 case 2:
422                     virtio_setup_queue(virtio, &virtio->ctrl_vq, pfn, page_addr);
423                     break;          
424                 default:
425                     break;
426             }
427             break;
428                 
429         case VRING_Q_SEL_PORT:
430             virtio->virtio_cfg.vring_queue_selector = *(uint16_t *)src;
431             if (virtio->virtio_cfg.vring_queue_selector > 2) {
432                 PrintError("Virtio NIC device only uses 3 queue, selected %d\n", 
433                            virtio->virtio_cfg.vring_queue_selector);
434                 return -1;
435             }
436             break;
437                 
438         case VRING_Q_NOTIFY_PORT: 
439             {
440                 uint16_t queue_idx = *(uint16_t *)src;                  
441                 if (queue_idx == 0){
442                     PrintDebug("receive queue notification 0, packet get by Guest\n");
443                 } else if (queue_idx == 1){
444                     if (handle_pkt_tx(virtio) == -1) {
445                         PrintError("Could not handle NIC Notification\n");
446                         return -1;
447                     }
448                 } else if (queue_idx == 2){
449                     if (handle_ctrl(virtio) == -1) {
450                         PrintError("Could not handle NIC Notification\n");
451                         return -1;
452                     }
453                 } else {
454                     PrintError("Virtio NIC device only uses 3 queue, selected %d\n", 
455                                queue_idx);
456                 }       
457                 break;          
458             }
459         
460         case VIRTIO_STATUS_PORT:
461             virtio->virtio_cfg.status = *(uint8_t *)src;
462             if (virtio->virtio_cfg.status == 0) {
463                 PrintDebug("Resetting device\n");
464                 virtio_init_state(virtio);
465             }
466             break;
467
468         case VIRTIO_ISR_PORT:
469             virtio->virtio_cfg.pci_isr = *(uint8_t *)src;
470             break;
471         default:
472             return -1;
473             break;
474     }
475
476     return length;
477 }
478
479 static int virtio_io_read(struct guest_info *core, uint16_t port, void * dst, uint_t length, void * private_data) 
480 {
481     struct virtio_net_state * virtio = (struct virtio_net_state *)private_data;
482     int port_idx = port % virtio->io_range_size;
483     uint16_t queue_idx = virtio->virtio_cfg.vring_queue_selector;
484
485     PrintDebug("Virtio NIC %p: Read  for port %d (index =%d), length=%d", private_data,
486                port, port_idx, length);
487         
488     switch (port_idx) {
489         case HOST_FEATURES_PORT:
490             if (length != 4) {
491                 PrintError("Illegal read length for host features\n");
492                 return -1;
493             }
494             *(uint32_t *)dst = virtio->virtio_cfg.host_features;
495             break;
496
497         case VRING_PG_NUM_PORT:
498             if (length != 4) {
499                 PrintError("Illegal read length for page frame number\n");
500                 return -1;
501             }
502             switch (queue_idx) {
503                 case 0:
504                     *(uint32_t *)dst = virtio->rx_vq.pfn;
505                     break;
506                 case 1:
507                     *(uint32_t *)dst = virtio->tx_vq.pfn;
508                     break;      
509                 case 2:
510                     *(uint32_t *)dst = virtio->ctrl_vq.pfn;
511                     break;
512                 default:
513                     break;
514             }
515             break;
516
517         case VRING_SIZE_PORT:
518             if (length != 2) {
519                 PrintError("Illegal read length for vring size\n");
520                 return -1;
521             }
522             switch (queue_idx) {
523                 case 0:
524                     *(uint16_t *)dst = virtio->rx_vq.queue_size;
525                     break;
526                 case 1:
527                     *(uint16_t *)dst = virtio->tx_vq.queue_size;
528                     break;      
529                 case 2:
530                     *(uint16_t *)dst = virtio->ctrl_vq.queue_size;
531                     break;
532                 default:
533                     break;
534             }
535             PrintDebug("queue index: %d, value=0x%x\n", (int)queue_idx, *(uint16_t *)dst);
536             break;
537
538         case VIRTIO_STATUS_PORT:
539             if (length != 1) {
540                 PrintError("Illegal read length for status\n");
541                 return -1;
542             }
543             *(uint8_t *)dst = virtio->virtio_cfg.status;
544             break;
545                 
546         case VIRTIO_ISR_PORT:
547             *(uint8_t *)dst = virtio->virtio_cfg.pci_isr;
548             virtio->virtio_cfg.pci_isr = 0;
549             v3_pci_lower_irq(virtio->virtio_dev->pci_bus, 0, virtio->pci_dev);
550             break;
551
552         default:
553             PrintError("Virtio NIC: Read of Unhandled Virtio Read\n");
554             return -1;
555     }
556
557     return length;
558 }
559
560
561 static struct v3_device_ops dev_ops = {
562     .free = virtio_free,
563     .reset = NULL,
564     .start = NULL,
565     .stop = NULL,
566 };
567
568 static int register_dev(struct virtio_dev_state * virtio, struct virtio_net_state * net_state) 
569 {
570     struct pci_device * pci_dev = NULL;
571     struct v3_pci_bar bars[6];
572     int num_ports = sizeof(struct virtio_config);
573     int tmp_ports = num_ports;
574     int i;
575
576     // This gets the number of ports, rounded up to a power of 2
577     net_state->io_range_size = 1; // must be a power of 2
578     while (tmp_ports > 0) {
579         tmp_ports >>= 1;
580         net_state->io_range_size <<= 1;
581     }
582         
583     // this is to account for any low order bits being set in num_ports
584     // if there are none, then num_ports was already a power of 2 so we shift right to reset it
585     if ((num_ports & ((net_state->io_range_size >> 1) - 1)) == 0) {
586         net_state->io_range_size >>= 1;
587     }
588     
589     for (i = 0; i < 6; i++) {
590         bars[i].type = PCI_BAR_NONE;
591     }
592     
593     PrintDebug("Virtio-NIC io_range_size = %d\n", net_state->io_range_size);
594     
595     bars[0].type = PCI_BAR_IO;
596     bars[0].default_base_port = -1;
597     bars[0].num_ports = net_state->io_range_size;
598     bars[0].io_read = virtio_io_read;
599     bars[0].io_write = virtio_io_write;
600     bars[0].private_data = net_state;
601     
602     pci_dev = v3_pci_register_device(virtio->pci_bus, PCI_STD_DEVICE, 
603                                      0, PCI_AUTO_DEV_NUM, 0,
604                                      "LNX_VIRTIO_NIC", bars,
605                                      NULL, NULL, NULL, net_state);
606     
607     if (!pci_dev) {
608         PrintError("Virtio NIC: Could not register PCI Device\n");
609         return -1;
610     }
611
612     PrintDebug("Virtio NIC:  registered to PCI bus\n");
613     
614     pci_dev->config_header.vendor_id = VIRTIO_VENDOR_ID;
615     pci_dev->config_header.subsystem_vendor_id = VIRTIO_SUBVENDOR_ID;
616         
617
618     pci_dev->config_header.device_id = VIRTIO_NET_DEV_ID;
619     pci_dev->config_header.class = PCI_CLASS_NETWORK;
620     pci_dev->config_header.subclass = PCI_NET_SUBCLASS_OTHER;  
621     pci_dev->config_header.subsystem_id = VIRTIO_NET_SUBDEVICE_ID;
622     pci_dev->config_header.intr_pin = 1;
623     pci_dev->config_header.max_latency = 1; // ?? (qemu does it...)
624
625     net_state->pci_dev = pci_dev;   
626     net_state->virtio_cfg.host_features = 0; //no features support now
627     net_state->rx_vq.queue_size = QUEUE_SIZE;
628     net_state->tx_vq.queue_size = QUEUE_SIZE;
629     net_state->ctrl_vq.queue_size = CTRL_QUEUE_SIZE;
630     net_state->virtio_dev = virtio;
631    
632     virtio_init_state(net_state);
633
634     return 0;
635 }
636
637 static int connect_fn(struct v3_vm_info * info, 
638                       void * frontend_data, 
639                       struct v3_dev_net_ops * ops, 
640                       v3_cfg_tree_t * cfg, 
641                       void * private_data) {
642     struct virtio_dev_state * virtio = (struct virtio_dev_state *)frontend_data;
643     struct virtio_net_state * net_state  = (struct virtio_net_state *)V3_Malloc(sizeof(struct virtio_net_state));
644
645     memset(net_state, 0, sizeof(struct virtio_net_state));
646     register_dev(virtio, net_state);
647
648     net_state->net_ops = ops;
649     net_state->backend_data = private_data;
650
651     //register input callback to the backend
652     net_state->net_ops->register_input(net_state->backend_data, virtio_dev_send, (void *)net_state);
653
654     return 0;
655 }
656
657 static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
658     struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
659     struct virtio_dev_state * virtio_state = NULL;
660     char * name = v3_cfg_val(cfg, "name");
661
662     PrintDebug("Virtio NIC: Initializing VIRTIO Network device: %s\n", name);
663
664     if (pci_bus == NULL) {
665         PrintError("Virtio NIC: VirtIO devices require a PCI Bus");
666         return -1;
667     }
668
669     virtio_state  = (struct virtio_dev_state *)V3_Malloc(sizeof(struct virtio_dev_state));
670     memset(virtio_state, 0, sizeof(struct virtio_dev_state));
671
672     INIT_LIST_HEAD(&(virtio_state->dev_list));
673     virtio_state->pci_bus = pci_bus;
674
675     struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state);
676     if (v3_attach_device(vm, dev) == -1) {
677         PrintError("Virtio NIC: Could not attach device %s\n", name);
678         return -1;
679     }
680
681     if (v3_dev_add_net_frontend(vm, name, connect_fn, (void *)virtio_state) == -1) {
682         PrintError("Virtio NIC: Could not register %s as net frontend\n", name);
683         return -1;
684     }
685         
686     return 0;
687 }
688
689 device_register("LNX_VIRTIO_NIC", virtio_init)
690