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.


6300eb8aa1e4380091533670da65ce354629728d
[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) 2010, Lei Xia <lxia@northwestern.edu>
11  * Copyright (c) 2010, Cui Zheng <cuizheng@cs.unm.edu>
12  * Copyright (c) 2010, 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 <vnet/vnet.h>
29 #include <palacios/vmm_lock.h>
30 #include <palacios/vmm_util.h>
31 #include <devices/pci.h>
32 #include <palacios/vmm_ethernet.h>
33 #include <palacios/vmm_time.h>
34
35
36 #ifndef V3_CONFIG_DEBUG_VIRTIO_NET
37 #undef PrintDebug
38 #define PrintDebug(fmt, args...)
39 #endif
40
41 #ifndef V3_CONFIG_VNET
42 static int net_debug = 0;
43 #endif
44
45 #define TX_QUEUE_SIZE 4096
46 #define RX_QUEUE_SIZE 4096
47 #define CTRL_QUEUE_SIZE 64
48
49 /* The feature bitmap for virtio nic
50   * from Linux */
51 #define VIRTIO_NET_F_CSUM       0       /* Host handles pkts w/ partial csum */
52 #define VIRTIO_NET_F_GUEST_CSUM 1       /* Guest handles pkts w/ partial csum */
53 #define VIRTIO_NET_F_MAC        5       /* Host has given MAC address. */
54 #define VIRTIO_NET_F_GSO        6       /* Host handles pkts w/ any GSO type */
55 #define VIRTIO_NET_F_GUEST_TSO4 7       /* Guest can handle TSOv4 in. */
56 #define VIRTIO_NET_F_GUEST_TSO6 8       /* Guest can handle TSOv6 in. */
57 #define VIRTIO_NET_F_GUEST_ECN  9       /* Guest can handle TSO[6] w/ ECN in. */
58 #define VIRTIO_NET_F_GUEST_UFO  10      /* Guest can handle UFO in. */
59 #define VIRTIO_NET_F_HOST_TSO4  11      /* Host can handle TSOv4 in. */
60 #define VIRTIO_NET_F_HOST_TSO6  12      /* Host can handle TSOv6 in. */
61 #define VIRTIO_NET_F_HOST_ECN   13      /* Host can handle TSO[6] w/ ECN in. */
62 #define VIRTIO_NET_F_HOST_UFO   14      /* Host can handle UFO in. */
63 #define VIRTIO_NET_F_MRG_RXBUF  15      /* Host can merge receive buffers. */
64 #define VIRTIO_NET_F_STATUS     16      /* virtio_net_config.status available */
65
66 /* Port to get virtio config */
67 #define VIRTIO_NET_CONFIG 20  
68
69 #define VIRTIO_NET_MAX_BUFSIZE (sizeof(struct virtio_net_hdr) + (64 << 10))
70
71 /* for gso_type in virtio_net_hdr */
72 #define VIRTIO_NET_HDR_GSO_NONE         0      
73 #define VIRTIO_NET_HDR_GSO_TCPV4        1     /* GSO frame, IPv4 TCP (TSO) */
74 #define VIRTIO_NET_HDR_GSO_UDP          3       /* GSO frame, IPv4 UDP (UFO) */
75 #define VIRTIO_NET_HDR_GSO_TCPV6        4       /* GSO frame, IPv6 TCP */
76 #define VIRTIO_NET_HDR_GSO_ECN          0x80    /* TCP has ECN set */   
77
78
79 /* for flags in virtio_net_hdr */
80 #define VIRTIO_NET_HDR_F_NEEDS_CSUM     1       /* Use csum_start, csum_offset */
81
82
83 /* First element of the scatter-gather list, used with GSO or CSUM features */
84 struct virtio_net_hdr
85 {
86     uint8_t flags;
87     uint8_t gso_type;
88     uint16_t hdr_len;           /* Ethernet + IP + tcp/udp hdrs */
89     uint16_t gso_size;          /* Bytes to append to hdr_len per frame */
90     uint16_t csum_start;        /* Position to start checksumming from */
91     uint16_t csum_offset;       /* Offset after that to place checksum */
92 }__attribute__((packed));
93
94
95 /* The header to use when the MRG_RXBUF 
96  * feature has been negotiated. */
97 struct virtio_net_hdr_mrg_rxbuf {
98     struct virtio_net_hdr hdr;
99     uint16_t num_buffers;       /* Number of merged rx buffers */
100 };
101
102 struct virtio_net_config
103 {
104     uint8_t mac[ETH_ALEN];      /* VIRTIO_NET_F_MAC */
105     uint16_t status;
106 } __attribute__((packed));
107
108 struct virtio_dev_state {
109     struct vm_device * pci_bus;
110     struct list_head dev_list;
111     struct v3_vm_info *vm;
112
113     uint8_t mac[ETH_ALEN];
114 };
115
116 struct virtio_net_state {
117     struct virtio_net_config net_cfg;
118     struct virtio_config virtio_cfg;
119
120     struct v3_vm_info * vm;
121     struct vm_device * dev;
122     struct pci_device * pci_dev; 
123     int io_range_size;
124
125     uint16_t status;
126     
127     struct virtio_queue rx_vq;          /* idx 0*/
128     struct virtio_queue tx_vq;          /* idx 1*/
129     struct virtio_queue ctrl_vq;        /* idx 2*/
130
131     uint8_t mergeable_rx_bufs;
132
133     struct v3_timer * timer;
134     struct vnet_thread * poll_thread;
135
136     struct nic_statistics stats;
137
138     struct v3_dev_net_ops * net_ops;
139     v3_lock_t rx_lock, tx_lock;
140
141     uint8_t tx_notify, rx_notify;
142     uint32_t tx_pkts, rx_pkts;
143     uint64_t past_us;
144
145     void * backend_data;
146     struct virtio_dev_state * virtio_dev;
147     struct list_head dev_link;
148 };
149
150
151 static int virtio_init_state(struct virtio_net_state * virtio) 
152 {
153     virtio->rx_vq.queue_size = RX_QUEUE_SIZE;
154     virtio->tx_vq.queue_size = TX_QUEUE_SIZE;
155     virtio->ctrl_vq.queue_size = CTRL_QUEUE_SIZE;
156
157     virtio->rx_vq.ring_desc_addr = 0;
158     virtio->rx_vq.ring_avail_addr = 0;
159     virtio->rx_vq.ring_used_addr = 0;
160     virtio->rx_vq.pfn = 0;
161     virtio->rx_vq.cur_avail_idx = 0;
162
163     virtio->tx_vq.ring_desc_addr = 0;
164     virtio->tx_vq.ring_avail_addr = 0;
165     virtio->tx_vq.ring_used_addr = 0;
166     virtio->tx_vq.pfn = 0;
167     virtio->tx_vq.cur_avail_idx = 0;
168
169     virtio->ctrl_vq.ring_desc_addr = 0;
170     virtio->ctrl_vq.ring_avail_addr = 0;
171     virtio->ctrl_vq.ring_used_addr = 0;
172     virtio->ctrl_vq.pfn = 0;
173     virtio->ctrl_vq.cur_avail_idx = 0;
174
175     virtio->virtio_cfg.pci_isr = 0;
176
177     virtio->mergeable_rx_bufs = 1;
178         
179     virtio->virtio_cfg.host_features = 0 | (1 << VIRTIO_NET_F_MAC);
180     if(virtio->mergeable_rx_bufs) {
181         virtio->virtio_cfg.host_features |= (1 << VIRTIO_NET_F_MRG_RXBUF);
182     }
183
184     if ((v3_lock_init(&(virtio->rx_lock)) == -1) ||
185         (v3_lock_init(&(virtio->tx_lock)) == -1)){
186         PrintError("Virtio NIC: Failure to init locks for net_state\n");
187     }
188
189     return 0;
190 }
191
192 static int tx_one_pkt(struct guest_info * core, 
193                       struct virtio_net_state * virtio, 
194                       struct vring_desc * buf_desc) 
195 {
196     uint8_t * buf = NULL;
197     uint32_t len = buf_desc->length;
198
199     if (v3_gpa_to_hva(core, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) {
200         PrintDebug("Could not translate buffer address\n");
201         return -1;
202     }
203
204     V3_Net_Print(2, "Virtio-NIC: virtio_tx: size: %d\n", len);
205     if(net_debug >= 4){
206         v3_hexdump(buf, len, NULL, 0);
207     }
208
209     if(virtio->net_ops->send(buf, len, virtio->backend_data) < 0){
210         virtio->stats.tx_dropped ++;
211         return -1;
212     }
213
214     virtio->stats.tx_pkts ++;
215     virtio->stats.tx_bytes += len;
216
217     return 0;
218 }
219
220
221 /*copy data into ring buffer */
222 static inline int copy_data_to_desc(struct guest_info * core, 
223                                     struct virtio_net_state * virtio_state, 
224                                     struct vring_desc * desc, 
225                                     uchar_t * buf, 
226                                     uint_t buf_len,
227                                     uint_t dst_offset){
228     uint32_t len;
229     uint8_t * desc_buf = NULL;
230
231     if (v3_gpa_to_hva(core, desc->addr_gpa, (addr_t *)&(desc_buf)) == -1) {
232         PrintDebug("Could not translate buffer address\n");
233         return -1;
234     }
235     len = (desc->length < (buf_len+dst_offset))?(desc->length - dst_offset):buf_len;
236     memcpy(desc_buf + dst_offset, buf, len);
237
238     return len;
239 }
240
241
242 static inline int get_desc_count(struct virtio_queue * q, int index) {
243     struct vring_desc * tmp_desc = &(q->desc[index]);
244     int cnt = 1;
245     
246     while (tmp_desc->flags & VIRTIO_NEXT_FLAG) {
247         tmp_desc = &(q->desc[tmp_desc->next]);
248         cnt++;
249     }
250
251     return cnt;
252 }
253
254 static inline void enable_cb(struct virtio_queue *queue){
255     if(queue->used){
256         queue->used->flags &= ~ VRING_NO_NOTIFY_FLAG;
257     }
258 }
259
260 static inline void disable_cb(struct virtio_queue *queue) {
261     if(queue->used){
262         queue->used->flags |= VRING_NO_NOTIFY_FLAG;
263     }
264 }
265
266 static int handle_pkt_tx(struct guest_info * core, 
267                          struct virtio_net_state * virtio_state,
268                          int quote)
269 {
270     struct virtio_queue *q = &(virtio_state->tx_vq);
271     int txed = 0, left = 0;
272     unsigned long flags;
273
274     if (!q->ring_avail_addr) {
275         return -1;
276     }
277
278     flags = v3_lock_irqsave(virtio_state->tx_lock);
279     while (q->cur_avail_idx != q->avail->index) {
280         struct virtio_net_hdr_mrg_rxbuf * hdr = NULL;
281         struct vring_desc * hdr_desc = NULL;
282         addr_t hdr_addr = 0;
283         uint16_t desc_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
284         int desc_cnt = get_desc_count(q, desc_idx);
285
286         if(desc_cnt != 2){
287             PrintError("VNIC: merged rx buffer not supported, desc_cnt %d\n", desc_cnt);
288             goto exit_error;
289         }
290
291         hdr_desc = &(q->desc[desc_idx]);
292         if (v3_gpa_to_hva(core, hdr_desc->addr_gpa, &(hdr_addr)) == -1) {
293             PrintError("Could not translate block header address\n");
294             goto exit_error;
295         }
296
297         hdr = (struct virtio_net_hdr_mrg_rxbuf *)hdr_addr;
298         desc_idx = hdr_desc->next;
299
300         V3_Net_Print(2, "Virtio NIC: TX hdr count : %d\n", hdr->num_buffers);
301
302         /* here we assumed that one ethernet pkt is not splitted into multiple buffer */        
303         struct vring_desc * buf_desc = &(q->desc[desc_idx]);
304         if (tx_one_pkt(core, virtio_state, buf_desc) == -1) {
305             PrintError("Virtio NIC: Error handling nic operation\n");
306             goto exit_error;
307         }
308         if(buf_desc->next & VIRTIO_NEXT_FLAG){
309             PrintError("Virtio NIC: TX more buffer need to read\n");
310         }
311             
312         q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
313         q->used->ring[q->used->index % q->queue_size].length = buf_desc->length; /* What do we set this to???? */
314         q->used->index ++;
315         
316         q->cur_avail_idx ++;
317         
318         if(++txed >= quote && quote > 0){
319             left = (q->cur_avail_idx != q->avail->index);
320             break;
321         }
322     }
323
324     v3_unlock_irqrestore(virtio_state->tx_lock, flags);
325
326     if (txed && !(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
327         v3_pci_raise_irq(virtio_state->virtio_dev->pci_bus, 
328                          0, virtio_state->pci_dev);
329         virtio_state->virtio_cfg.pci_isr = 0x1;
330         virtio_state->stats.rx_interrupts ++;
331     }
332
333     V3_Print("Virtio Intr Line %d\n", virtio_state->pci_dev->config_header.intr_line);
334
335     if(txed > 0) {
336         V3_Net_Print(2, "Virtio Handle TX: txed pkts: %d, left %d\n", txed, left);
337     }
338
339     return left;
340
341 exit_error:
342         
343     v3_unlock_irqrestore(virtio_state->tx_lock, flags);
344     return -1;
345 }
346
347
348 static int virtio_setup_queue(struct guest_info *core, 
349                               struct virtio_net_state * virtio_state, 
350                               struct virtio_queue * queue, 
351                               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 (v3_gpa_to_hva(core, 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 (v3_gpa_to_hva(core, 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 (v3_gpa_to_hva(core, 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, 
389                            uint16_t port, void * src, 
390                            uint_t length, void * private_data) 
391 {
392     struct virtio_net_state * virtio = (struct virtio_net_state *)private_data;
393     int port_idx = port % virtio->io_range_size;
394
395     PrintDebug("VIRTIO NIC %p Write for port %d (index=%d) len=%d, value=%x\n",
396                private_data, port, port_idx,  
397                length, *(uint32_t *)src);
398
399     switch (port_idx) {
400         case GUEST_FEATURES_PORT:
401             if (length != 4) {
402                 PrintError("Illegal write length for guest features\n");
403                 return -1;
404             }       
405             virtio->virtio_cfg.guest_features = *(uint32_t *)src;
406             break;
407                 
408         case VRING_PG_NUM_PORT:
409             if (length != 4) {
410                 PrintError("Illegal write length for page frame number\n");
411                 return -1;
412             }
413             addr_t pfn = *(uint32_t *)src;
414             addr_t page_addr = (pfn << VIRTIO_PAGE_SHIFT);
415             uint16_t queue_idx = virtio->virtio_cfg.vring_queue_selector;
416             switch (queue_idx) {
417                 case 0:
418                     virtio_setup_queue(core, virtio,
419                                        &virtio->rx_vq, 
420                                        pfn, page_addr);
421                     break;
422                 case 1:
423                     virtio_setup_queue(core, virtio, 
424                                        &virtio->tx_vq, 
425                                        pfn, page_addr);
426                     if(virtio->tx_notify == 0){
427                         disable_cb(&virtio->tx_vq);
428                         vnet_thread_wakeup(virtio->poll_thread);
429                     }
430                     break;
431                 case 2:
432                     virtio_setup_queue(core, virtio, 
433                                        &virtio->ctrl_vq, 
434                                        pfn, page_addr);
435                     break;          
436                 default:
437                     break;
438             }
439             break;
440                 
441         case VRING_Q_SEL_PORT:
442             virtio->virtio_cfg.vring_queue_selector = *(uint16_t *)src;
443             if (virtio->virtio_cfg.vring_queue_selector > 2) {
444                 PrintError("Virtio NIC: wrong queue idx: %d\n", 
445                            virtio->virtio_cfg.vring_queue_selector);
446                 return -1;
447             }
448             break;
449                 
450         case VRING_Q_NOTIFY_PORT: 
451             {
452                 uint16_t queue_idx = *(uint16_t *)src;                  
453                 if (queue_idx == 0){
454                     /* receive queue refill */
455                     virtio->stats.tx_interrupts ++;
456                 } else if (queue_idx == 1){
457                     if (handle_pkt_tx(core, virtio, 0) < 0) {
458                         PrintError("Virtio NIC: Error to handle packet TX\n");
459                         return -1;
460                     }
461                     virtio->stats.tx_interrupts ++;
462                 } else if (queue_idx == 2){
463                     /* ctrl */
464                 } else {
465                     PrintError("Virtio NIC: Wrong queue index %d\n", queue_idx);
466                 }       
467                 break;          
468             }
469         
470         case VIRTIO_STATUS_PORT:
471             virtio->virtio_cfg.status = *(uint8_t *)src;
472             if (virtio->virtio_cfg.status == 0) {
473                 virtio_init_state(virtio);
474             }
475             break;
476
477         case VIRTIO_ISR_PORT:
478             virtio->virtio_cfg.pci_isr = *(uint8_t *)src;
479             break;
480                 
481         default:
482             return -1;
483             break;
484     }
485
486     return length;
487 }
488
489 static int virtio_io_read(struct guest_info *core, 
490                           uint16_t port, void * dst, 
491                           uint_t length, void * private_data) 
492 {
493     struct virtio_net_state * virtio = (struct virtio_net_state *)private_data;
494     int port_idx = port % virtio->io_range_size;
495     uint16_t queue_idx = virtio->virtio_cfg.vring_queue_selector;
496
497     PrintDebug("Virtio NIC %p: Read  for port 0x%x (index =%d), length=%d\n", 
498                private_data, port, port_idx, length);
499         
500     switch (port_idx) {
501         case HOST_FEATURES_PORT:
502             if (length != 4) {
503                 PrintError("Virtio NIC: Illegal read length for host features\n");
504                 //return -1;
505             }
506             *(uint32_t *)dst = virtio->virtio_cfg.host_features;
507             break;
508
509         case VRING_PG_NUM_PORT:
510             if (length != 4) {
511                 PrintError("Virtio NIC: Illegal read length for page frame number\n");
512                 return -1;
513             }
514             switch (queue_idx) {
515                 case 0:
516                     *(uint32_t *)dst = virtio->rx_vq.pfn;
517                     break;
518                 case 1:
519                     *(uint32_t *)dst = virtio->tx_vq.pfn;
520                     break;      
521                 case 2:
522                     *(uint32_t *)dst = virtio->ctrl_vq.pfn;
523                     break;
524                 default:
525                     break;
526             }
527             break;
528
529         case VRING_SIZE_PORT:
530             if (length != 2) {
531                 PrintError("Virtio NIC: Illegal read length for vring size\n");
532                 return -1;
533             }
534             switch (queue_idx) {
535                 case 0:
536                     *(uint16_t *)dst = virtio->rx_vq.queue_size;
537                     break;
538                 case 1:
539                     *(uint16_t *)dst = virtio->tx_vq.queue_size;
540                     break;      
541                 case 2:
542                     *(uint16_t *)dst = virtio->ctrl_vq.queue_size;
543                     break;
544                 default:
545                     break;
546             }
547             break;
548
549         case VIRTIO_STATUS_PORT:
550             if (length != 1) {
551                 PrintError("Virtio NIC: Illegal read length for status\n");
552                 return -1;
553             }
554             *(uint8_t *)dst = virtio->virtio_cfg.status;
555             break;
556                 
557         case VIRTIO_ISR_PORT:
558             *(uint8_t *)dst = virtio->virtio_cfg.pci_isr;
559             virtio->virtio_cfg.pci_isr = 0;
560             v3_pci_lower_irq(virtio->virtio_dev->pci_bus, 
561                              0, virtio->pci_dev);
562             break;
563
564         case VIRTIO_NET_CONFIG ... VIRTIO_NET_CONFIG + ETH_ALEN:
565             *(uint8_t *)dst = virtio->net_cfg.mac[port_idx-VIRTIO_NET_CONFIG];
566             break;
567
568         default:
569             PrintError("Virtio NIC: Read of Unhandled Virtio Read:%d\n", 
570                        port_idx);
571             return -1;
572     }
573
574     return length;
575 }
576
577
578 /* receiving raw ethernet pkt from backend */
579 static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) {
580     struct virtio_net_state * virtio = (struct virtio_net_state *)private_data;
581     struct virtio_queue * q = &(virtio->rx_vq);
582     struct virtio_net_hdr_mrg_rxbuf hdr;
583     unsigned long flags;
584     uint8_t kick_guest = 0;
585
586     V3_Net_Print(2, "Virtio NIC: virtio_rx: size: %d\n", size);
587
588     if (!q->ring_avail_addr) {
589         V3_Net_Print(2, "Virtio NIC: RX Queue not set\n");
590         virtio->stats.rx_dropped ++;
591         
592         return -1;
593     }
594
595     memset(&hdr, 0, sizeof(struct virtio_net_hdr_mrg_rxbuf));
596
597     flags = v3_lock_irqsave(virtio->rx_lock);
598
599     if (q->cur_avail_idx != q->avail->index){
600         uint16_t buf_idx;
601         struct vring_desc * buf_desc;
602         uint32_t hdr_len, len;
603         uint32_t offset = 0;
604
605         hdr_len = (virtio->mergeable_rx_bufs)?
606             sizeof(struct virtio_net_hdr_mrg_rxbuf):
607             sizeof(struct virtio_net_hdr);
608
609         if(virtio->mergeable_rx_bufs){/* merged buffer */
610             struct vring_desc * hdr_desc;
611             uint16_t old_idx = q->cur_avail_idx;
612
613             buf_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
614             hdr_desc = &(q->desc[buf_idx]);
615
616             len = copy_data_to_desc(&(virtio->virtio_dev->vm->cores[0]), 
617                                     virtio, hdr_desc, buf, size, hdr_len);
618             if(len < 0){
619                 goto err_exit;
620             }
621             offset += len;
622
623             q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
624             q->used->ring[q->used->index % q->queue_size].length = hdr_len + offset;
625             q->cur_avail_idx ++;
626             hdr.num_buffers ++;
627
628             while(offset < size) {
629                 buf_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
630                 buf_desc = &(q->desc[buf_idx]);
631
632                 len = copy_data_to_desc(&(virtio->virtio_dev->vm->cores[0]), 
633                                         virtio, buf_desc, buf+offset, size-offset, 0);  
634                 if (len < 0){
635                     V3_Net_Print(2, "Virtio NIC: merged buffer, %d buffer size %d\n", 
636                                  hdr.num_buffers, len);
637                     q->cur_avail_idx = old_idx;
638                     goto err_exit;
639                 }
640                 offset += len;
641                 buf_desc->flags &= ~VIRTIO_NEXT_FLAG;
642
643                 q->used->ring[(q->used->index + hdr.num_buffers) % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
644                 q->used->ring[(q->used->index + hdr.num_buffers) % q->queue_size].length = len;
645                 q->cur_avail_idx ++;   
646
647                 hdr.num_buffers ++;
648             }
649
650             copy_data_to_desc(&(virtio->virtio_dev->vm->cores[0]), 
651                               virtio, hdr_desc, (uchar_t *)&hdr, hdr_len, 0);
652             q->used->index += hdr.num_buffers;
653         }else{
654             buf_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
655             buf_desc = &(q->desc[buf_idx]);
656
657             /* copy header */
658             len = copy_data_to_desc(&(virtio->virtio_dev->vm->cores[0]), 
659                                     virtio, buf_desc, (uchar_t *)&(hdr.hdr), hdr_len, 0);
660             if(len < hdr_len){
661                 V3_Net_Print(2, "Virtio NIC: rx copy header error %d, hdr_len %d\n", 
662                              len, hdr_len);
663                 goto err_exit;
664             }
665
666             len = copy_data_to_desc(&(virtio->virtio_dev->vm->cores[0]), 
667                                     virtio, buf_desc, buf, size, hdr_len);
668             if(len < 0){
669                 V3_Net_Print(2, "Virtio NIC: rx copy data error %d\n", len);
670                 goto err_exit;
671             }
672             offset += len;
673
674             /* copy rest of data */
675             while(offset < size && 
676                   (buf_desc->flags & VIRTIO_NEXT_FLAG)){
677                 buf_desc = &(q->desc[buf_desc->next]);
678                 len = copy_data_to_desc(&(virtio->virtio_dev->vm->cores[0]), 
679                                         virtio, buf_desc, buf+offset, size-offset, 0);      
680                 if (len < 0) {
681                     break;
682                 }
683                 offset += len;
684             }
685             buf_desc->flags &= ~VIRTIO_NEXT_FLAG;
686
687             if(offset < size){
688                 V3_Net_Print(2, "Virtio NIC: rx not enough ring buffer, buffer size %d\n", 
689                              len);
690                 goto err_exit;
691             }
692                 
693             q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
694             q->used->ring[q->used->index % q->queue_size].length = size + hdr_len; /* This should be the total length of data sent to guest (header+pkt_data) */
695             q->used->index ++;
696             q->cur_avail_idx ++;
697         } 
698
699         virtio->stats.rx_pkts ++;
700         virtio->stats.rx_bytes += size;
701     } else {
702         V3_Net_Print(2, "Virtio NIC: Guest RX queue is full\n");
703         virtio->stats.rx_dropped ++;
704
705         /* kick guest to refill RX queue */
706         kick_guest = 1;
707     }
708
709     v3_unlock_irqrestore(virtio->rx_lock, flags);
710
711     if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG) || kick_guest) {
712         V3_Net_Print(2, "Virtio NIC: RX Raising IRQ %d\n",  
713                      virtio->pci_dev->config_header.intr_line);
714
715         virtio->virtio_cfg.pci_isr = 0x1;       
716         v3_pci_raise_irq(virtio->virtio_dev->pci_bus, 0, virtio->pci_dev);
717         virtio->stats.rx_interrupts ++;
718     }
719
720     /* notify guest if it is in guest mode */
721     if((kick_guest || virtio->rx_notify == 1) && 
722         V3_Get_CPU() != virtio->virtio_dev->vm->cores[0].pcpu_id){
723         v3_interrupt_cpu(virtio->virtio_dev->vm, 
724                          virtio->virtio_dev->vm->cores[0].pcpu_id, 
725                          0);
726     }
727
728     return 0;
729
730 err_exit:
731     virtio->stats.rx_dropped ++;
732     v3_unlock_irqrestore(virtio->rx_lock, flags);
733  
734     return -1;
735 }
736
737 static int virtio_free(struct virtio_dev_state * virtio) {
738     struct virtio_net_state * backend = NULL;
739     struct virtio_net_state * tmp = NULL;
740
741
742     list_for_each_entry_safe(backend, tmp, &(virtio->dev_list), dev_link) {
743
744         // unregister from PCI
745
746         list_del(&(backend->dev_link));
747         V3_Free(backend);
748     }
749
750     V3_Free(virtio);
751     return 0;
752 }
753
754
755 static struct v3_device_ops dev_ops = {
756     .free = (int (*)(void *))virtio_free,
757 };
758
759
760 static int virtio_poll(int quote, void * data){
761     struct virtio_net_state * virtio  = (struct virtio_net_state *)data;
762
763     return handle_pkt_tx(&(virtio->vm->cores[0]), virtio, quote);
764 }
765
766 static int register_dev(struct virtio_dev_state * virtio, 
767                         struct virtio_net_state * net_state) 
768 {
769     struct pci_device * pci_dev = NULL;
770     struct v3_pci_bar bars[6];
771     int num_ports = sizeof(struct virtio_config);
772     int tmp_ports = num_ports;
773     int i;
774
775     /* This gets the number of ports, rounded up to a power of 2 */
776     net_state->io_range_size = 1;
777     while (tmp_ports > 0) {
778         tmp_ports >>= 1;
779         net_state->io_range_size <<= 1;
780     }
781         
782     /* this is to account for any low order bits being set in num_ports
783      * if there are none, then num_ports was already a power of 2 so we shift right to reset it
784      */
785     if ((num_ports & ((net_state->io_range_size >> 1) - 1)) == 0) {
786         net_state->io_range_size >>= 1;
787     }
788     
789     for (i = 0; i < 6; i++) {
790         bars[i].type = PCI_BAR_NONE;
791     }
792     
793     PrintDebug("Virtio NIC: io_range_size = %d\n", 
794                net_state->io_range_size);
795     
796     bars[0].type = PCI_BAR_IO;
797     bars[0].default_base_port = -1;
798     bars[0].num_ports = net_state->io_range_size;
799     bars[0].io_read = virtio_io_read;
800     bars[0].io_write = virtio_io_write;
801     bars[0].private_data = net_state;
802     
803     pci_dev = v3_pci_register_device(virtio->pci_bus, PCI_STD_DEVICE, 
804                                      0, PCI_AUTO_DEV_NUM, 0,
805                                      "LNX_VIRTIO_NIC", bars,
806                                      NULL, NULL, NULL, net_state);
807     
808     if (!pci_dev) {
809         PrintError("Virtio NIC: Could not register PCI Device\n");
810         return -1;
811     }
812
813     PrintDebug("Virtio NIC:  registered to PCI bus\n");
814     
815     pci_dev->config_header.vendor_id = VIRTIO_VENDOR_ID;
816     pci_dev->config_header.subsystem_vendor_id = VIRTIO_SUBVENDOR_ID;
817         
818
819     pci_dev->config_header.device_id = VIRTIO_NET_DEV_ID;
820     pci_dev->config_header.class = PCI_CLASS_NETWORK;
821     pci_dev->config_header.subclass = PCI_NET_SUBCLASS_OTHER;  
822     pci_dev->config_header.subsystem_id = VIRTIO_NET_SUBDEVICE_ID;
823     pci_dev->config_header.intr_pin = 1;
824     pci_dev->config_header.max_latency = 1; // ?? (qemu does it...)
825
826     net_state->pci_dev = pci_dev;
827     net_state->virtio_dev = virtio;
828
829     memcpy(net_state->net_cfg.mac, virtio->mac, 6);                           
830         
831     virtio_init_state(net_state);
832
833     V3_Print("Virtio NIC: Registered Intr Line %d\n", pci_dev->config_header.intr_line);
834
835     /* Add backend to list of devices */
836     list_add(&(net_state->dev_link), &(virtio->dev_list));
837
838     return 0;
839 }
840
841
842 #define RATE_UPPER_THRESHOLD 10  /* 10000 pkts per second, around 100Mbits */
843 #define RATE_LOWER_THRESHOLD 1
844 #define PROFILE_PERIOD 10000 /*us*/
845
846 static void virtio_nic_timer(struct guest_info * core, 
847                              uint64_t cpu_cycles, uint64_t cpu_freq, 
848                              void * priv_data) {
849     struct virtio_net_state * net_state = (struct virtio_net_state *)priv_data;
850     uint64_t period_us;
851     static int profile_ms = 0;
852
853     if(!net_state->status){ /* VNIC is not in working status */
854         return;
855     }
856
857     period_us = (1000*cpu_cycles)/cpu_freq;
858     net_state->past_us += period_us;
859
860     if(net_state->past_us > PROFILE_PERIOD){ 
861         uint32_t tx_rate, rx_rate;
862         
863         tx_rate = (net_state->stats.tx_pkts - net_state->tx_pkts)/(net_state->past_us/1000); /* pkts/per ms */
864         rx_rate = (net_state->stats.rx_pkts - net_state->rx_pkts)/(net_state->past_us/1000);
865
866         net_state->tx_pkts = net_state->stats.tx_pkts;
867         net_state->rx_pkts = net_state->stats.rx_pkts;
868
869         if(tx_rate > RATE_UPPER_THRESHOLD && net_state->tx_notify == 1){
870             V3_Print("Virtio NIC: Switch TX to VMM driven mode\n");
871             disable_cb(&(net_state->tx_vq));
872             net_state->tx_notify = 0;
873             vnet_thread_wakeup(net_state->poll_thread);
874         }
875
876         if(tx_rate < RATE_LOWER_THRESHOLD && net_state->tx_notify == 0){
877             V3_Print("Virtio NIC: Switch TX to Guest  driven mode\n");
878             enable_cb(&(net_state->tx_vq));
879             net_state->tx_notify = 1;
880         }
881
882         if(rx_rate > RATE_UPPER_THRESHOLD && net_state->rx_notify == 1){
883             V3_Print("Virtio NIC: Switch RX to VMM None notify mode\n");
884             net_state->rx_notify = 0;
885         }
886
887         if(rx_rate < RATE_LOWER_THRESHOLD && net_state->rx_notify == 0){
888             V3_Print("Virtio NIC: Switch RX to VMM notify mode\n");
889             net_state->rx_notify = 1;
890         }
891
892         net_state->past_us = 0;
893     }
894
895     profile_ms += period_us/1000;
896     if(profile_ms > 20000){
897         V3_Net_Print(1, "Virtio NIC: TX: Pkt: %lld, Bytes: %lld\n\t\tRX Pkt: %lld. Bytes: %lld\n\t\tDropped: tx %lld, rx %lld\nInterrupts: tx %d, rx %d\nTotal Exit: %lld\n",
898                 net_state->stats.tx_pkts, net_state->stats.tx_bytes,
899                 net_state->stats.rx_pkts, net_state->stats.rx_bytes,
900                 net_state->stats.tx_dropped, net_state->stats.rx_dropped,
901                 net_state->stats.tx_interrupts, net_state->stats.rx_interrupts,
902                 net_state->vm->cores[0].num_exits);
903         profile_ms = 0;
904     }
905 }
906
907 static struct v3_timer_ops timer_ops = {
908     .update_timer = virtio_nic_timer,
909 };
910
911
912 static int connect_fn(struct v3_vm_info * info, 
913                       void * frontend_data, 
914                       struct v3_dev_net_ops * ops, 
915                       v3_cfg_tree_t * cfg, 
916                       void * private_data) {
917     struct virtio_dev_state * virtio = (struct virtio_dev_state *)frontend_data;
918     struct virtio_net_state * net_state  = (struct virtio_net_state *)V3_Malloc(sizeof(struct virtio_net_state));
919
920     memset(net_state, 0, sizeof(struct virtio_net_state));
921     register_dev(virtio, net_state);
922
923     net_state->vm = info;
924     net_state->net_ops = ops;
925     net_state->backend_data = private_data;
926     net_state->virtio_dev = virtio;
927     net_state->tx_notify = 0;
928     net_state->rx_notify = 0;
929         
930     net_state->timer = v3_add_timer(&(info->cores[0]),
931                                     &timer_ops,net_state);
932
933     ops->recv = virtio_rx;
934     ops->poll = virtio_poll;
935     ops->config.frontend_data = net_state;
936     ops->config.poll = 1;
937     ops->config.quote = 64;
938     ops->config.fnt_mac = V3_Malloc(ETH_ALEN);  
939     memcpy(ops->config.fnt_mac, virtio->mac, ETH_ALEN);
940
941     net_state->status = 1;
942
943     return 0;
944 }
945
946 static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
947     struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
948     struct virtio_dev_state * virtio_state = NULL;
949     char * dev_id = v3_cfg_val(cfg, "ID");
950     char macstr[128];
951     char * str = v3_cfg_val(cfg, "mac");
952     memcpy(macstr, str, strlen(str));
953
954     if (pci_bus == NULL) {
955         PrintError("Virtio NIC: Virtio device require a PCI Bus");
956         return -1;
957     }
958
959     virtio_state  = (struct virtio_dev_state *)V3_Malloc(sizeof(struct virtio_dev_state));
960     memset(virtio_state, 0, sizeof(struct virtio_dev_state));
961
962     INIT_LIST_HEAD(&(virtio_state->dev_list));
963     virtio_state->pci_bus = pci_bus;
964     virtio_state->vm = vm;
965
966     if (macstr != NULL && !str2mac(macstr, virtio_state->mac)) {
967         PrintDebug("Virtio NIC: Mac specified %s\n", macstr);
968     }else {
969         random_ethaddr(virtio_state->mac);
970     }
971
972     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, virtio_state);
973
974     if (dev == NULL) {
975         PrintError("Virtio NIC: Could not attach device %s\n", dev_id);
976         V3_Free(virtio_state);
977         return -1;
978     }
979
980     if (v3_dev_add_net_frontend(vm, dev_id, connect_fn, (void *)virtio_state) == -1) {
981         PrintError("Virtio NIC: Could not register %s as net frontend\n", dev_id);
982         v3_remove_device(dev);
983         return -1;
984     }
985         
986     return 0;
987 }
988
989 device_register("LNX_VIRTIO_NIC", virtio_init)
990