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 MAC address configure support on Virtio NIC
[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 <palacios/vmm_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
34
35 #ifndef CONFIG_DEBUG_VIRTIO_NET
36 #undef PrintDebug
37 #define PrintDebug(fmt, args...)
38 #endif
39
40 #define VIRTIO_NET_S_LINK_UP    1       /* Link is up */
41 #define VIRTIO_NET_MAX_BUFSIZE (sizeof(struct virtio_net_hdr) + (64 << 10))
42
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 /* This is the version of the header to use when the MRG_RXBUF
57  * feature has been negotiated. */
58 struct virtio_net_hdr_mrg_rxbuf {
59         struct virtio_net_hdr hdr;
60         uint16_t num_buffers;   /* Number of merged rx buffers */
61 };
62
63         
64 #define TX_QUEUE_SIZE 64
65 #define RX_QUEUE_SIZE 1024
66 #define CTRL_QUEUE_SIZE 64
67
68 #define VIRTIO_NET_F_MRG_RXBUF  15      /* Host can merge receive buffers. */
69 #define VIRTIO_NET_F_MAC        5       /* Host has given MAC address. */
70 #define VIRTIO_NET_F_GSO        6       /* Host handles pkts w/ any GSO type */
71 #define VIRTIO_NET_F_HOST_TSO4  11      /* Host can handle TSOv4 in. */
72
73 /* this is not how virtio supposed to be,
74  * we may need a separately implemented virtio_pci
75  * In order to make guest to get virtio MAC from host
76  * I added it here  -- Lei
77  */
78  #define VIRTIO_NET_CONFIG 20  
79
80
81 struct virtio_net_config
82 {
83     uint8_t mac[ETH_ALEN];      /* VIRTIO_NET_F_MAC */
84     uint16_t status;
85 } __attribute__((packed));
86
87 struct virtio_dev_state {
88     struct vm_device * pci_bus;
89     struct list_head dev_list;
90     struct v3_vm_info *vm;
91
92     char mac[ETH_ALEN];
93 };
94
95 struct virtio_net_state {
96     struct virtio_net_config net_cfg;
97     struct virtio_config virtio_cfg;
98
99     struct vm_device * dev;
100     struct pci_device * pci_dev; 
101     int io_range_size;
102     
103     struct virtio_queue rx_vq;          /* idx 0, pkts to guest */
104     struct virtio_queue tx_vq;          /* idx 1, pkts from guest */
105     struct virtio_queue ctrl_vq;        /* idx 2 */
106
107     int buffed_rx;
108     int tx_disabled;                    /* stop TX pkts from guest */
109
110     uint64_t pkt_sent, pkt_recv, pkt_drop;
111
112     struct v3_dev_net_ops * net_ops;
113     v3_lock_t rx_lock, tx_lock;
114
115     void * backend_data;
116     struct virtio_dev_state * virtio_dev;
117     struct list_head dev_link;
118 };
119
120 /* virtio nic error type */
121 #define ERR_VIRTIO_OTHER  1
122 #define ERR_VIRTIO_RXQ_FULL  2
123 #define ERR_VIRTIO_RXQ_NOSET  3
124 #define ERR_VIRTIO_TXQ_NOSET 4
125 #define ERR_VIRTIO_TXQ_FULL 5
126 #define ERR_VIRTIO_TXQ_DISABLED 6
127
128
129
130
131 static int virtio_init_state(struct virtio_net_state * virtio) 
132 {
133     virtio->rx_vq.queue_size = RX_QUEUE_SIZE;
134     virtio->tx_vq.queue_size = TX_QUEUE_SIZE;
135     virtio->ctrl_vq.queue_size = CTRL_QUEUE_SIZE;
136
137     virtio->rx_vq.ring_desc_addr = 0;
138     virtio->rx_vq.ring_avail_addr = 0;
139     virtio->rx_vq.ring_used_addr = 0;
140     virtio->rx_vq.pfn = 0;
141     virtio->rx_vq.cur_avail_idx = 0;
142
143     virtio->tx_vq.ring_desc_addr = 0;
144     virtio->tx_vq.ring_avail_addr = 0;
145     virtio->tx_vq.ring_used_addr = 0;
146     virtio->tx_vq.pfn = 0;
147     virtio->tx_vq.cur_avail_idx = 0;
148
149     virtio->ctrl_vq.ring_desc_addr = 0;
150     virtio->ctrl_vq.ring_avail_addr = 0;
151     virtio->ctrl_vq.ring_used_addr = 0;
152     virtio->ctrl_vq.pfn = 0;
153     virtio->ctrl_vq.cur_avail_idx = 0;
154
155     virtio->virtio_cfg.pci_isr = 0;
156         
157     virtio->virtio_cfg.host_features = 0 | (1 << VIRTIO_NET_F_MAC);
158
159     if ((v3_lock_init(&(virtio->rx_lock)) == -1) ||
160         (v3_lock_init(&(virtio->tx_lock)) == -1)){
161         PrintError("Virtio NIC: Failure to init locks for net_state\n");
162     }
163
164     virtio->pkt_sent = virtio->pkt_recv = virtio->pkt_drop = 0;
165     virtio->buffed_rx = 0;
166
167     return 0;
168 }
169
170 static int 
171 pkt_tx(struct guest_info * core, 
172        struct virtio_net_state * virtio, 
173        struct vring_desc * buf_desc) 
174 {
175     uint8_t * buf = NULL;
176     uint32_t len = buf_desc->length;
177
178     if (v3_gpa_to_hva(core, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) {
179         PrintError("Could not translate buffer address\n");
180         return -ERR_VIRTIO_OTHER;
181     }
182
183     return virtio->net_ops->send(buf, len, virtio->backend_data);
184 }
185
186
187 static int 
188 copy_data_to_desc(struct guest_info * core, 
189                   struct virtio_net_state * virtio_state, 
190                   struct vring_desc * desc, 
191                   uchar_t * buf, 
192                   uint_t buf_len,
193                   uint_t offset)
194 {
195     uint32_t len;
196     uint8_t * desc_buf = NULL;
197
198     if (v3_gpa_to_hva(core, desc->addr_gpa, (addr_t *)&(desc_buf)) == -1) {
199         PrintError("Could not translate buffer address\n");
200         return -1;
201     }
202     len = (desc->length < buf_len)?(desc->length - offset):buf_len;
203     memcpy(desc_buf+offset, buf, len);
204
205     return len;
206 }
207
208
209 static int get_desc_count(struct virtio_queue * q, int index) {
210     struct vring_desc * tmp_desc = &(q->desc[index]);
211     int cnt = 1;
212     
213     while (tmp_desc->flags & VIRTIO_NEXT_FLAG) {
214         tmp_desc = &(q->desc[tmp_desc->next]);
215         cnt++;
216     }
217
218     return cnt;
219 }
220
221 static inline void enable_cb(struct virtio_queue *queue){
222     queue->used->flags &= ~ VRING_NO_NOTIFY_FLAG;
223 }
224
225 static inline void disable_cb(struct virtio_queue *queue) {
226     queue->used->flags |= VRING_NO_NOTIFY_FLAG;
227 }
228
229
230 /* interrupt the guest, so the guest core get EXIT to Palacios
231  * this happens when there are either incoming pkts for the guest
232  * or the guest can start TX pkts again */
233 static inline void notify_guest(struct virtio_net_state * virtio){
234     v3_interrupt_cpu(virtio->virtio_dev->vm, virtio->virtio_dev->vm->cores[0].cpu_id, 0);
235 }
236
237
238 /* guest free some pkts from rx queue */
239 static int handle_rx_kick(struct guest_info *core, 
240                           struct virtio_net_state * virtio) 
241 {
242     unsigned long flags;
243
244     flags = v3_lock_irqsave(virtio->rx_lock);
245
246     if(virtio->net_ops->start_rx != NULL){
247         virtio->net_ops->start_rx(virtio->backend_data);
248     }
249         //disable_cb(&virtio->rx_vq);
250
251     v3_unlock_irqrestore(virtio->rx_lock, flags);
252         
253     return 0;
254 }
255
256
257 static int handle_ctrl(struct guest_info *core, 
258                        struct virtio_net_state * virtio) {
259         
260     return 0;
261 }
262
263 static int handle_pkt_tx(struct guest_info *core, 
264                          struct virtio_net_state * virtio_state) 
265 {
266     struct virtio_queue * q = &(virtio_state->tx_vq);
267     struct virtio_net_hdr * hdr = NULL;
268     int recved = 0;
269     unsigned long flags;
270
271     if (!q->ring_avail_addr) 
272         return -ERR_VIRTIO_TXQ_NOSET;
273
274     if(virtio_state->tx_disabled)
275         return -ERR_VIRTIO_TXQ_DISABLED;
276
277     flags = v3_lock_irqsave(virtio_state->tx_lock);
278     while (q->cur_avail_idx != q->avail->index) {
279         struct vring_desc * hdr_desc = NULL;
280         addr_t hdr_addr = 0;
281         uint16_t desc_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
282         int desc_cnt = get_desc_count(q, desc_idx);
283         uint32_t req_len = 0;
284         int i = 0;
285
286         hdr_desc = &(q->desc[desc_idx]);
287         if (v3_gpa_to_hva(core, hdr_desc->addr_gpa, &(hdr_addr)) == -1) {
288             PrintError("Could not translate block header address\n");
289             goto exit_error;
290         }
291
292         hdr = (struct virtio_net_hdr*)hdr_addr;
293         desc_idx = hdr_desc->next;
294
295         if(desc_cnt > 2){
296             PrintError("VNIC: merged rx buffer not supported\n");
297             goto exit_error;
298         }
299
300         /* here we assumed that one ethernet pkt is not splitted into multiple virtio buffer */
301         for (i = 0; i < desc_cnt - 1; i++) {    
302             struct vring_desc * buf_desc = &(q->desc[desc_idx]);
303             if (pkt_tx(core, virtio_state, buf_desc) == -1) {
304                 PrintError("Error handling nic operation\n");
305                 goto exit_error;
306             }
307
308             req_len += buf_desc->length;
309             desc_idx = buf_desc->next;
310         }
311         virtio_state->pkt_sent ++;
312         recved ++;
313
314         q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
315         q->used->ring[q->used->index % q->queue_size].length = req_len; // What do we set this to????
316         q->used->index ++;
317         
318         q->cur_avail_idx ++;
319     }
320
321     v3_unlock_irqrestore(virtio_state->tx_lock, flags);
322
323     if(!recved)
324         return 0;
325         
326     if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
327         v3_pci_raise_irq(virtio_state->virtio_dev->pci_bus, 0, virtio_state->pci_dev);
328         virtio_state->virtio_cfg.pci_isr = 0x1;
329     }
330
331     return 0;
332
333 exit_error:
334         
335     v3_unlock_irqrestore(virtio_state->tx_lock, flags);
336     return -ERR_VIRTIO_OTHER;
337 }
338
339
340 static int virtio_setup_queue(struct guest_info *core, 
341                               struct virtio_net_state * virtio_state, 
342                               struct virtio_queue * queue, 
343                               addr_t pfn, addr_t page_addr) {
344     queue->pfn = pfn;
345                 
346     queue->ring_desc_addr = page_addr;
347     queue->ring_avail_addr = page_addr + (queue->queue_size * sizeof(struct vring_desc));
348     queue->ring_used_addr = ((queue->ring_avail_addr) + 
349                              (sizeof(struct vring_avail)) + 
350                              (queue->queue_size * sizeof(uint16_t)));
351
352     // round up to next page boundary.
353     queue->ring_used_addr = (queue->ring_used_addr + 0xfff) & ~0xfff;
354     if (v3_gpa_to_hva(core, queue->ring_desc_addr, (addr_t *)&(queue->desc)) == -1) {
355         PrintError("Could not translate ring descriptor address\n");
356          return -1;
357     }
358  
359     if (v3_gpa_to_hva(core, queue->ring_avail_addr, (addr_t *)&(queue->avail)) == -1) {
360         PrintError("Could not translate ring available address\n");
361         return -1;
362     }
363
364     if (v3_gpa_to_hva(core, queue->ring_used_addr, (addr_t *)&(queue->used)) == -1) {
365         PrintError("Could not translate ring used address\n");
366         return -1;
367     }
368
369     PrintDebug("RingDesc_addr=%p, Avail_addr=%p, Used_addr=%p\n",
370                (void *)(queue->ring_desc_addr),
371                (void *)(queue->ring_avail_addr),
372                (void *)(queue->ring_used_addr));
373     
374     PrintDebug("RingDesc=%p, Avail=%p, Used=%p\n", 
375                queue->desc, queue->avail, queue->used);
376     
377     return 0;
378 }
379
380 static int virtio_io_write(struct guest_info *core, 
381                            uint16_t port, void * src, 
382                            uint_t length, void * private_data) 
383 {
384     struct virtio_net_state * virtio = (struct virtio_net_state *)private_data;
385     int port_idx = port % virtio->io_range_size;
386
387     PrintDebug("VIRTIO NIC %p Write for port %d (index=%d) len=%d, value=%x\n", private_data,
388                port, port_idx,  length, *(uint32_t *)src);
389
390     switch (port_idx) {
391         case GUEST_FEATURES_PORT:
392             if (length != 4) {
393                 PrintError("Illegal write length for guest features\n");
394                 return -1;
395             }       
396             virtio->virtio_cfg.guest_features = *(uint32_t *)src;
397             break;
398                 
399         case VRING_PG_NUM_PORT:
400             if (length != 4) {
401                 PrintError("Illegal write length for page frame number\n");
402                 return -1;
403             }
404             addr_t pfn = *(uint32_t *)src;
405             addr_t page_addr = (pfn << VIRTIO_PAGE_SHIFT);
406             uint16_t queue_idx = virtio->virtio_cfg.vring_queue_selector;
407             switch (queue_idx) {
408                 case 0:
409                     virtio_setup_queue(core, virtio, &virtio->rx_vq, pfn, page_addr);
410                     //disable_cb(&virtio->rx_vq);
411                     break;
412                 case 1:
413                     virtio_setup_queue(core, virtio, &virtio->tx_vq, pfn, page_addr);
414                     //disable_cb(&virtio->tx_vq);
415                     break;
416                 case 2:
417                     virtio_setup_queue(core, virtio, &virtio->ctrl_vq, pfn, page_addr);
418                     break;          
419                 default:
420                     break;
421             }
422             break;
423                 
424         case VRING_Q_SEL_PORT:
425             virtio->virtio_cfg.vring_queue_selector = *(uint16_t *)src;
426             if (virtio->virtio_cfg.vring_queue_selector > 2) {
427                 PrintError("Virtio NIC: wrong queue idx: %d\n", 
428                            virtio->virtio_cfg.vring_queue_selector);
429                 return -1;
430             }
431             break;
432                 
433         case VRING_Q_NOTIFY_PORT: 
434             {
435                 uint16_t queue_idx = *(uint16_t *)src;                  
436                 if (queue_idx == 0){
437                     handle_rx_kick(core, virtio);
438                 } else if (queue_idx == 1){
439                     if (handle_pkt_tx(core, virtio) == -1) {
440                         PrintError("Could not handle NIC Notification\n");
441                         return -1;
442                     }
443                 } else if (queue_idx == 2){
444                     if (handle_ctrl(core, virtio) == -1) {
445                         PrintError("Could not handle NIC Notification\n");
446                         return -1;
447                     }
448                 } else {
449                     PrintError("Wrong queue index %d\n", queue_idx);
450                 }       
451                 break;          
452             }
453         
454         case VIRTIO_STATUS_PORT:
455             virtio->virtio_cfg.status = *(uint8_t *)src;
456             if (virtio->virtio_cfg.status == 0) {
457                 PrintDebug("Resetting device\n");
458                 virtio_init_state(virtio);
459             }
460             break;
461
462         case VIRTIO_ISR_PORT:
463             virtio->virtio_cfg.pci_isr = *(uint8_t *)src;
464             break;
465                 
466         default:
467             return -1;
468             break;
469     }
470
471     return length;
472 }
473
474 static int virtio_io_read(struct guest_info *core, 
475                           uint16_t port, void * dst, 
476                           uint_t length, void * private_data) 
477 {
478     struct virtio_net_state * virtio = (struct virtio_net_state *)private_data;
479     int port_idx = port % virtio->io_range_size;
480     uint16_t queue_idx = virtio->virtio_cfg.vring_queue_selector;
481
482     PrintDebug("Virtio NIC %p: Read  for port 0x%x (index =%d), length=%d\n", private_data,
483                port, port_idx, length);
484         
485     switch (port_idx) {
486         case HOST_FEATURES_PORT:
487             if (length != 4) {
488                 PrintError("Illegal read length for host features\n");
489                 return -1;
490             }
491             *(uint32_t *)dst = virtio->virtio_cfg.host_features;
492             break;
493
494         case VRING_PG_NUM_PORT:
495             if (length != 4) {
496                 PrintError("Illegal read length for page frame number\n");
497                 return -1;
498             }
499             switch (queue_idx) {
500                 case 0:
501                     *(uint32_t *)dst = virtio->rx_vq.pfn;
502                     break;
503                 case 1:
504                     *(uint32_t *)dst = virtio->tx_vq.pfn;
505                     break;      
506                 case 2:
507                     *(uint32_t *)dst = virtio->ctrl_vq.pfn;
508                     break;
509                 default:
510                     break;
511             }
512             break;
513
514         case VRING_SIZE_PORT:
515             if (length != 2) {
516                 PrintError("Illegal read length for vring size\n");
517                 return -1;
518             }
519             switch (queue_idx) {
520                 case 0:
521                     *(uint16_t *)dst = virtio->rx_vq.queue_size;
522                     break;
523                 case 1:
524                     *(uint16_t *)dst = virtio->tx_vq.queue_size;
525                     break;      
526                 case 2:
527                     *(uint16_t *)dst = virtio->ctrl_vq.queue_size;
528                     break;
529                 default:
530                     break;
531             }
532             break;
533
534         case VIRTIO_STATUS_PORT:
535             if (length != 1) {
536                 PrintError("Illegal read length for status\n");
537                 return -1;
538             }
539             *(uint8_t *)dst = virtio->virtio_cfg.status;
540             break;
541                 
542         case VIRTIO_ISR_PORT:
543             *(uint8_t *)dst = virtio->virtio_cfg.pci_isr;
544             virtio->virtio_cfg.pci_isr = 0;
545             v3_pci_lower_irq(virtio->virtio_dev->pci_bus, 0, virtio->pci_dev);
546             break;
547
548         case VIRTIO_NET_CONFIG ... VIRTIO_NET_CONFIG + ETH_ALEN:
549             *(uint8_t *)dst = virtio->net_cfg.mac[port_idx-VIRTIO_NET_CONFIG];
550             break;
551
552         default:
553             PrintError("Virtio NIC: Read of Unhandled Virtio Read:%d\n", port_idx);
554             return -1;
555     }
556
557     return length;
558 }
559
560
561 static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) {
562     struct virtio_net_state * virtio = (struct virtio_net_state *)private_data;
563     struct virtio_queue * q = &(virtio->rx_vq);
564     struct virtio_net_hdr_mrg_rxbuf hdr;
565     uint32_t hdr_len = sizeof(struct virtio_net_hdr_mrg_rxbuf);
566     uint32_t data_len = size;
567     uint32_t offset = 0;
568     unsigned long flags;
569     int ret_val = -ERR_VIRTIO_OTHER;
570     int raw = 1;
571
572 #ifndef CONFIG_DEBUG_VIRTIO_NET
573    {
574         PrintDebug("Virtio-NIC: virtio_rx: size: %d\n", size);  
575         //v3_hexdump(buf, size, NULL, 0);
576    }
577 #endif
578
579     flags = v3_lock_irqsave(virtio->rx_lock);
580
581     virtio->pkt_recv ++;
582     if (!raw)
583         data_len -= hdr_len;
584
585     if (!raw)
586         memcpy(&hdr, buf, sizeof(struct virtio_net_hdr_mrg_rxbuf));
587     else
588         memset(&hdr, 0, sizeof(struct virtio_net_hdr_mrg_rxbuf));
589
590     if (q->ring_avail_addr == 0) {
591         PrintError("Queue is not set\n");
592         ret_val = -ERR_VIRTIO_RXQ_NOSET;
593         goto exit;
594     }
595
596     if (q->cur_avail_idx != q->avail->index){
597         addr_t hdr_addr = 0;
598         uint16_t hdr_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
599         uint16_t buf_idx = 0;
600         struct vring_desc * hdr_desc = NULL;
601
602         hdr_desc = &(q->desc[hdr_idx]);
603         if (v3_gpa_to_hva(&(virtio->virtio_dev->vm->cores[0]), hdr_desc->addr_gpa, &(hdr_addr)) == -1) {
604             PrintError("Could not translate receive buffer address\n");
605             goto exit;
606         }
607         hdr.num_buffers = 1;
608         memcpy((void *)hdr_addr, &hdr, sizeof(struct virtio_net_hdr_mrg_rxbuf));
609         if (offset >= data_len) {
610             hdr_desc->flags &= ~VIRTIO_NEXT_FLAG;
611         }
612
613         struct vring_desc * buf_desc = NULL;
614         for (buf_idx = hdr_desc->next; offset < data_len; buf_idx = q->desc[hdr_idx].next) {
615             uint32_t len = 0;
616             buf_desc = &(q->desc[buf_idx]);
617
618             len = copy_data_to_desc(&(virtio->virtio_dev->vm->cores[0]), virtio, buf_desc, buf + offset, data_len - offset, 0);     
619             offset += len;
620             if (offset < data_len) {
621                 buf_desc->flags = VIRTIO_NEXT_FLAG;             
622             }
623             buf_desc->length = len;
624         }
625         buf_desc->flags &= ~VIRTIO_NEXT_FLAG;
626         
627         q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
628         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) */
629         q->used->index++;
630         q->cur_avail_idx++;
631
632         /* if there are certain num of pkts in the RX queue, notify guest 
633           * so guest will exit to palacios
634          * when it returns, guest gets the virtio rx interrupt */
635         if((++virtio->buffed_rx > q->queue_size/5) &&
636             (q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
637             if(virtio->virtio_dev->vm->cores[0].cpu_id != V3_Get_CPU()){
638                   notify_guest(virtio);
639             }
640             virtio->buffed_rx = 0;
641         }
642     } else {
643         virtio->pkt_drop++;
644         /* RX queue is full,  tell backend to stop RX on this device */
645         virtio->net_ops->stop_rx(virtio->backend_data);
646         enable_cb(&virtio->rx_vq);
647         
648         ret_val = -ERR_VIRTIO_RXQ_FULL;
649         goto exit;
650     }
651
652     if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
653         PrintDebug("Raising IRQ %d\n",  virtio->pci_dev->config_header.intr_line);
654         v3_pci_raise_irq(virtio->virtio_dev->pci_bus, 0, virtio->pci_dev);
655         virtio->virtio_cfg.pci_isr = 0x1;
656     }
657
658     ret_val = offset;
659
660 exit:
661
662     v3_unlock_irqrestore(virtio->rx_lock, flags);
663  
664     return ret_val;
665 }
666
667 static int virtio_free(struct virtio_dev_state * virtio) {
668     struct virtio_net_state * backend = NULL;
669     struct virtio_net_state * tmp = NULL;
670
671
672     list_for_each_entry_safe(backend, tmp, &(virtio->dev_list), dev_link) {
673
674         // unregister from PCI
675
676         list_del(&(backend->dev_link));
677         V3_Free(backend);
678     }
679
680     V3_Free(virtio);
681     return 0;
682 }
683
684
685 static struct v3_device_ops dev_ops = {
686     .free = (int (*)(void *))virtio_free,
687 };
688
689
690 /* TODO: Issue here: which vm info it needs? calling VM or the device's own VM? */
691 static void virtio_nic_poll(struct v3_vm_info * vm, void * data){
692     struct virtio_net_state * virtio = (struct virtio_net_state *)data;
693         
694     handle_pkt_tx(&(vm->cores[0]), virtio);
695 }
696
697 static void virtio_start_tx(void * data){
698     struct virtio_net_state * virtio = (struct virtio_net_state *)data;
699     unsigned long flags;
700
701     flags = v3_lock_irqsave(virtio->tx_lock);
702     virtio->tx_disabled = 0;
703
704     /* notify the device's guest to start sending pkt */
705     if(virtio->virtio_dev->vm->cores[0].cpu_id != V3_Get_CPU()){
706         notify_guest(virtio);
707     }
708     v3_unlock_irqrestore(virtio->tx_lock, flags);       
709 }
710
711 static void virtio_stop_tx(void * data){
712     struct virtio_net_state * virtio = (struct virtio_net_state *)data;
713     unsigned long flags;
714
715     flags = v3_lock_irqsave(virtio->tx_lock);
716     virtio->tx_disabled = 1;
717
718     /* stop the guest to exit to palacios for sending pkt? */
719     if(virtio->virtio_dev->vm->cores[0].cpu_id != V3_Get_CPU()){
720        disable_cb(&virtio->tx_vq);
721     }
722
723     v3_unlock_irqrestore(virtio->tx_lock, flags);
724 }
725
726         
727
728
729 static int register_dev(struct virtio_dev_state * virtio, 
730                         struct virtio_net_state * net_state) 
731 {
732     struct pci_device * pci_dev = NULL;
733     struct v3_pci_bar bars[6];
734     int num_ports = sizeof(struct virtio_config);
735     int tmp_ports = num_ports;
736     int i;
737
738     // This gets the number of ports, rounded up to a power of 2
739     net_state->io_range_size = 1; // must be a power of 2
740     while (tmp_ports > 0) {
741         tmp_ports >>= 1;
742         net_state->io_range_size <<= 1;
743     }
744         
745     // this is to account for any low order bits being set in num_ports
746     // if there are none, then num_ports was already a power of 2 so we shift right to reset it
747     if ((num_ports & ((net_state->io_range_size >> 1) - 1)) == 0) {
748         net_state->io_range_size >>= 1;
749     }
750     
751     for (i = 0; i < 6; i++) {
752         bars[i].type = PCI_BAR_NONE;
753     }
754     
755     PrintDebug("Virtio-NIC io_range_size = %d\n", net_state->io_range_size);
756     
757     bars[0].type = PCI_BAR_IO;
758     bars[0].default_base_port = -1;
759     bars[0].num_ports = net_state->io_range_size;
760     bars[0].io_read = virtio_io_read;
761     bars[0].io_write = virtio_io_write;
762     bars[0].private_data = net_state;
763     
764     pci_dev = v3_pci_register_device(virtio->pci_bus, PCI_STD_DEVICE, 
765                                      0, 4/*PCI_AUTO_DEV_NUM*/, 0,
766                                      "LNX_VIRTIO_NIC", bars,
767                                      NULL, NULL, NULL, net_state);
768     
769     if (!pci_dev) {
770         PrintError("Virtio NIC: Could not register PCI Device\n");
771         return -1;
772     }
773
774     PrintDebug("Virtio NIC:  registered to PCI bus\n");
775     
776     pci_dev->config_header.vendor_id = VIRTIO_VENDOR_ID;
777     pci_dev->config_header.subsystem_vendor_id = VIRTIO_SUBVENDOR_ID;
778         
779
780     pci_dev->config_header.device_id = VIRTIO_NET_DEV_ID;
781     pci_dev->config_header.class = PCI_CLASS_NETWORK;
782     pci_dev->config_header.subclass = PCI_NET_SUBCLASS_OTHER;  
783     pci_dev->config_header.subsystem_id = VIRTIO_NET_SUBDEVICE_ID;
784     pci_dev->config_header.intr_pin = 1;
785     pci_dev->config_header.max_latency = 1; // ?? (qemu does it...)
786
787     net_state->pci_dev = pci_dev;
788     net_state->virtio_dev = virtio;
789
790     memcpy(net_state->net_cfg.mac, virtio->mac, 6);                           
791         
792     virtio_init_state(net_state);
793
794     /* Add backend to list of devices */
795     list_add(&(net_state->dev_link), &(virtio->dev_list));
796
797     return 0;
798 }
799
800 static int connect_fn(struct v3_vm_info * info, 
801                       void * frontend_data, 
802                       struct v3_dev_net_ops * ops, 
803                       v3_cfg_tree_t * cfg, 
804                       void * private_data) {
805     struct virtio_dev_state * virtio = (struct virtio_dev_state *)frontend_data;
806     struct virtio_net_state * net_state  = (struct virtio_net_state *)V3_Malloc(sizeof(struct virtio_net_state));
807
808     memset(net_state, 0, sizeof(struct virtio_net_state));
809     register_dev(virtio, net_state);
810
811     net_state->net_ops = ops;
812     net_state->backend_data = private_data;
813     net_state->virtio_dev = virtio;
814         
815
816     ops->recv = virtio_rx;
817     ops->poll = virtio_nic_poll;
818     ops->start_tx = virtio_start_tx;
819     ops->stop_tx = virtio_stop_tx;
820     ops->frontend_data = net_state;
821     memcpy(ops->fnt_mac, virtio->mac, ETH_ALEN);
822
823     return 0;
824 }
825
826
827 static int str2mac(char * macstr, char * mac){
828     char hex[2], *s = macstr;
829     int i = 0;
830
831     while(s){
832         memcpy(hex, s, 2);
833         mac[i++] = (char)atox(hex);     
834         if (i == ETH_ALEN) return 0;
835         s=strchr(s, ':');
836         if(s) s++;
837     }
838
839     return -1;
840 }
841
842 static inline void random_ethaddr(uchar_t * addr)
843 {
844     uint64_t val;
845
846     /* using current rdtsc as random number */
847     rdtscll(val);
848     *(uint64_t *)addr = val;
849         
850     addr [0] &= 0xfe;   /* clear multicast bit */
851     addr [0] |= 0x02;   /* set local assignment bit (IEEE802) */
852 }
853
854
855 static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
856     struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
857     struct virtio_dev_state * virtio_state = NULL;
858     char * dev_id = v3_cfg_val(cfg, "ID");
859     char * macstr = v3_cfg_val(cfg, "mac");
860
861     if (pci_bus == NULL) {
862         PrintError("Virtio NIC: VirtIO devices require a PCI Bus");
863         return -1;
864     }
865
866     virtio_state  = (struct virtio_dev_state *)V3_Malloc(sizeof(struct virtio_dev_state));
867     memset(virtio_state, 0, sizeof(struct virtio_dev_state));
868
869     INIT_LIST_HEAD(&(virtio_state->dev_list));
870     virtio_state->pci_bus = pci_bus;
871     virtio_state->vm = vm;
872
873     if (macstr != NULL && !str2mac(macstr, virtio_state->mac)) {
874         PrintDebug("Virtio NIC: Mac specified %s\n", macstr);
875     }else {
876         PrintDebug("Virtio NIC: MAC not specified\n");
877         random_ethaddr(virtio_state->mac);
878     }
879
880     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, virtio_state);
881
882     if (dev == NULL) {
883         PrintError("Virtio NIC: Could not attach device %s\n", dev_id);
884         V3_Free(virtio_state);
885         return -1;
886     }
887
888     if (v3_dev_add_net_frontend(vm, dev_id, connect_fn, (void *)virtio_state) == -1) {
889         PrintError("Virtio NIC: Could not register %s as net frontend\n", dev_id);
890         v3_remove_device(dev);
891         return -1;
892     }
893         
894     return 0;
895 }
896
897 device_register("LNX_VIRTIO_NIC", virtio_init)
898