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.


fixes for the virtio block device
[palacios.git] / palacios / src / devices / lnx_virtio_blk.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, Jack Lange <jarusl@cs.northwestern.edu>
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm.h>
21 #include <palacios/vmm_dev_mgr.h>
22 #include <devices/lnx_virtio_pci.h>
23 #include <devices/lnx_virtio_blk.h>
24 #include <devices/block_dev.h>
25 #include <palacios/vm_guest_mem.h>
26
27 #include <devices/pci.h>
28
29
30 #ifndef DEBUG_VIRTIO_BLK
31 #undef PrintDebug
32 #define PrintDebug(fmt, args...)
33 #endif
34
35 #define BLK_CAPACITY_PORT     20
36 #define BLK_MAX_SIZE_PORT     28
37 #define BLK_MAX_SEG_PORT      32
38 #define BLK_CYLINDERS_PORT    36
39 #define BLK_HEADS_PORT        38
40 #define BLK_SECTS_PORT        39
41
42 #define BLK_IN_REQ            0
43 #define BLK_OUT_REQ           1
44 #define BLK_SCSI_CMD          2
45
46 #define BLK_BARRIER_FLAG     0x80000000
47
48 #define BLK_STATUS_OK             0
49 #define BLK_STATUS_ERR            1
50 #define BLK_STATUS_NOT_SUPPORTED  2
51
52
53 struct blk_config {
54     uint64_t capacity;
55     uint32_t max_size;
56     uint32_t max_seg;
57     uint16_t cylinders;
58     uint8_t heads;
59     uint8_t sectors;
60 } __attribute__((packed));
61
62
63
64 struct blk_op_hdr {
65     uint32_t type;
66     uint32_t prior;
67     uint64_t sector;
68 } __attribute__((packed));
69
70 #define QUEUE_SIZE 128
71
72 /* Host Feature flags */
73 #define VIRTIO_BARRIER       0x01       /* Does host support barriers? */
74 #define VIRTIO_SIZE_MAX      0x02       /* Indicates maximum segment size */
75 #define VIRTIO_SEG_MAX       0x04       /* Indicates maximum # of segments */
76 #define VIRTIO_LEGACY_GEOM   0x10       /* Indicates support of legacy geometry */
77
78
79
80
81 struct virtio_blk_state {
82     struct blk_config block_cfg;
83     struct virtio_config virtio_cfg;
84
85     struct vm_device * pci_bus;
86     struct pci_device * pci_dev;
87     
88     struct virtio_queue queue;
89
90     union {
91         struct v3_cd_ops * cd_ops;
92         struct v3_hd_ops * hd_ops;
93     };
94
95     v3_block_type_t block_type;
96     void * backend_data;
97
98     int io_range_size;
99 };
100
101
102 static int virtio_free(struct vm_device * dev) {
103     return -1;
104 }
105
106 static int virtio_reset(struct vm_device * dev) {
107     struct virtio_blk_state * virtio = (struct virtio_blk_state *)dev->private_data;
108
109     virtio->queue.ring_desc_addr = 0;
110     virtio->queue.ring_avail_addr = 0;
111     virtio->queue.ring_used_addr = 0;
112     virtio->queue.pfn = 0;
113     virtio->queue.cur_avail_idx = 0;
114
115     virtio->virtio_cfg.status = 0;
116     virtio->virtio_cfg.pci_isr = 0;
117
118     return 0;
119 }
120
121 static int handle_read_op(struct vm_device * dev, uint8_t * buf, uint64_t * sector, uint32_t len) {
122     struct virtio_blk_state * virtio = (struct virtio_blk_state *)dev->private_data; 
123     int ret = -1;
124
125     if (virtio->block_type == BLOCK_DISK) {
126         if (len % HD_SECTOR_SIZE) {
127             PrintError("Write of something that is not a sector len %d, mod=%d\n", len, len % HD_SECTOR_SIZE);
128             return -1;
129         }
130
131
132         PrintDebug("Reading Disk\n");
133             
134         ret = virtio->hd_ops->read(buf, len / HD_SECTOR_SIZE, *sector, virtio->backend_data);
135
136         *sector += len / HD_SECTOR_SIZE;
137
138     } else if (virtio->block_type == BLOCK_CDROM) {
139         if (len % ATAPI_BLOCK_SIZE) {
140             PrintError("Write of something that is not an ATAPI block len %d, mod=%d\n", len, len % ATAPI_BLOCK_SIZE);
141             return -1;
142         }
143
144         ret = virtio->cd_ops->read(buf, len / ATAPI_BLOCK_SIZE, *sector , virtio->backend_data);
145
146         *sector += len / ATAPI_BLOCK_SIZE;
147     }
148
149     return ret;
150 }
151
152
153 static int handle_write_op(struct vm_device * dev, uint8_t * buf, uint64_t * sector, uint32_t len) {
154     struct virtio_blk_state * virtio = (struct virtio_blk_state *)dev->private_data; 
155     int ret = -1;
156
157     if (virtio->block_type == BLOCK_DISK) {
158         if (len % HD_SECTOR_SIZE) {
159             PrintError("Write of something that is not a sector len %d, mod=%d\n", len, len % HD_SECTOR_SIZE);
160             return -1;
161         }
162
163         PrintDebug("Writing Disk\n");
164
165         ret = virtio->hd_ops->write(buf, len / HD_SECTOR_SIZE, *sector, virtio->backend_data);
166
167         *sector += len / HD_SECTOR_SIZE;        
168     }
169
170     return ret;
171 }
172
173
174
175 // multiple block operations need to increment the sector 
176
177 static int handle_block_op(struct vm_device * dev, struct blk_op_hdr * hdr, 
178                            struct vring_desc * buf_desc, uint8_t * status) {
179     struct virtio_blk_state * virtio = (struct virtio_blk_state *)dev->private_data;    
180     uint8_t * buf = NULL;
181
182     PrintDebug("Handling Block op\n");
183
184
185
186     if (guest_pa_to_host_va(dev->vm, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) {
187         PrintError("Could not translate buffer address\n");
188         return -1;
189     }
190
191
192     PrintDebug("Sector=%p Length=%d\n", (void *)(addr_t)(hdr->sector), buf_desc->length);
193
194     if (hdr->type == BLK_IN_REQ) {
195         if (virtio->block_type != BLOCK_NONE) {
196             if (handle_read_op(dev, buf, &(hdr->sector), buf_desc->length) == -1) {
197                 *status = BLK_STATUS_ERR;
198                 return -1;
199             } else {
200                 *status = BLK_STATUS_OK;
201             }
202         } else {
203             *status = BLK_STATUS_NOT_SUPPORTED;
204         }
205
206     } else if (hdr->type == BLK_OUT_REQ) {
207         if (virtio->block_type == BLOCK_DISK) {
208             if (handle_write_op(dev, buf, &(hdr->sector), buf_desc->length) == -1) {
209                 *status = BLK_STATUS_ERR;
210                 return -1;
211             } else {
212                 *status = BLK_STATUS_OK;
213             }
214
215         } else {
216             *status = BLK_STATUS_NOT_SUPPORTED;
217         }
218
219     } else if (hdr->type == BLK_SCSI_CMD) {
220         PrintError("VIRTIO: SCSI Command Not supported!!!\n");
221         *status = BLK_STATUS_NOT_SUPPORTED;
222         return -1;
223     }
224
225
226
227     PrintDebug("Returning Status: %d\n", *status);
228
229     return 0;
230 }
231
232 static int get_desc_count(struct virtio_queue * q, int index) {
233     struct vring_desc * tmp_desc = &(q->desc[index]);
234     int cnt = 1;
235     
236     while (tmp_desc->flags & VIRTIO_NEXT_FLAG) {
237         tmp_desc = &(q->desc[tmp_desc->next]);
238         cnt++;
239     }
240
241     return cnt;
242 }
243
244
245
246 static int handle_kick(struct vm_device * dev) {
247     struct virtio_blk_state * virtio = (struct virtio_blk_state *)dev->private_data;    
248     struct virtio_queue * q = &(virtio->queue);
249
250     PrintDebug("VIRTIO KICK: cur_index=%d (mod=%d), avail_index=%d\n", 
251                q->cur_avail_idx, q->cur_avail_idx % QUEUE_SIZE, q->avail->index);
252
253     while (q->cur_avail_idx < q->avail->index) {
254         struct vring_desc * hdr_desc = NULL;
255         struct vring_desc * buf_desc = NULL;
256         struct vring_desc * status_desc = NULL;
257         struct blk_op_hdr hdr;
258         addr_t hdr_addr = 0;
259         uint16_t desc_idx = q->avail->ring[q->cur_avail_idx % QUEUE_SIZE];
260         int desc_cnt = get_desc_count(q, desc_idx);
261         int i = 0;
262         uint8_t * status_ptr = NULL;
263         uint8_t status = BLK_STATUS_OK;
264         uint32_t req_len = 0;
265
266         PrintDebug("Descriptor Count=%d, index=%d\n", desc_cnt, q->cur_avail_idx % QUEUE_SIZE);
267
268         if (desc_cnt < 3) {
269             PrintError("Block operations must include at least 3 descriptors\n");
270             return -1;
271         }
272
273         hdr_desc = &(q->desc[desc_idx]);
274
275
276         PrintDebug("Header Descriptor (ptr=%p) gpa=%p, len=%d, flags=%x, next=%d\n", hdr_desc, 
277                    (void *)(hdr_desc->addr_gpa), hdr_desc->length, hdr_desc->flags, hdr_desc->next);    
278
279         if (guest_pa_to_host_va(dev->vm, hdr_desc->addr_gpa, &(hdr_addr)) == -1) {
280             PrintError("Could not translate block header address\n");
281             return -1;
282         }
283
284         // We copy the block op header out because we are going to modify its contents
285         memcpy(&hdr, (void *)hdr_addr, sizeof(struct blk_op_hdr));
286         
287         PrintDebug("Blk Op Hdr (ptr=%p) type=%d, sector=%p\n", (void *)hdr_addr, hdr.type, (void *)hdr.sector);
288
289         desc_idx = hdr_desc->next;
290
291         for (i = 0; i < desc_cnt - 2; i++) {
292             uint8_t tmp_status = BLK_STATUS_OK;
293
294             buf_desc = &(q->desc[desc_idx]);
295
296             PrintDebug("Buffer Descriptor (ptr=%p) gpa=%p, len=%d, flags=%x, next=%d\n", buf_desc, 
297                        (void *)(buf_desc->addr_gpa), buf_desc->length, buf_desc->flags, buf_desc->next);
298
299             if (handle_block_op(dev, &hdr, buf_desc, &tmp_status) == -1) {
300                 PrintError("Error handling block operation\n");
301                 return -1;
302             }
303
304             if (tmp_status != BLK_STATUS_OK) {
305                 status = tmp_status;
306             }
307
308             req_len += buf_desc->length;
309             desc_idx = buf_desc->next;
310         }
311
312         status_desc = &(q->desc[desc_idx]);
313
314         PrintDebug("Status Descriptor (ptr=%p) gpa=%p, len=%d, flags=%x, next=%d\n", status_desc, 
315                    (void *)(status_desc->addr_gpa), status_desc->length, status_desc->flags, status_desc->next);
316
317         if (guest_pa_to_host_va(dev->vm, status_desc->addr_gpa, (addr_t *)&(status_ptr)) == -1) {
318             PrintError("Could not translate status address\n");
319             return -1;
320         }
321
322         req_len += status_desc->length;
323         *status_ptr = status;
324
325         q->used->ring[q->used->index % QUEUE_SIZE].id = q->avail->ring[q->cur_avail_idx % QUEUE_SIZE];
326         q->used->ring[q->used->index % QUEUE_SIZE].length = req_len; // What do we set this to????
327
328         q->used->index++;
329         q->cur_avail_idx++;
330     }
331
332     if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
333         PrintDebug("Raising IRQ %d\n",  virtio->pci_dev->config_header.intr_line);
334         v3_pci_raise_irq(virtio->pci_bus, 0, virtio->pci_dev);
335         virtio->virtio_cfg.pci_isr = 1;
336     }
337
338     return 0;
339 }
340
341 static int virtio_io_write(uint16_t port, void * src, uint_t length, struct vm_device * dev) {
342     struct virtio_blk_state * virtio = (struct virtio_blk_state *)dev->private_data;
343     int port_idx = port % virtio->io_range_size;
344
345
346     PrintDebug("VIRTIO BLOCK Write for port %d (index=%d) len=%d, value=%x\n", 
347                port, port_idx,  length, *(uint32_t *)src);
348
349
350
351     switch (port_idx) {
352         case GUEST_FEATURES_PORT:
353             if (length != 4) {
354                 PrintError("Illegal write length for guest features\n");
355                 return -1;
356             }
357             
358             virtio->virtio_cfg.guest_features = *(uint32_t *)src;
359             PrintDebug("Setting Guest Features to %x\n", virtio->virtio_cfg.guest_features);
360
361             break;
362         case VRING_PG_NUM_PORT:
363             if (length == 4) {
364                 addr_t pfn = *(uint32_t *)src;
365                 addr_t page_addr = (pfn << VIRTIO_PAGE_SHIFT);
366
367
368                 virtio->queue.pfn = pfn;
369                 
370                 virtio->queue.ring_desc_addr = page_addr ;
371                 virtio->queue.ring_avail_addr = page_addr + (QUEUE_SIZE * sizeof(struct vring_desc));
372                 virtio->queue.ring_used_addr = ( virtio->queue.ring_avail_addr + \
373                                                  sizeof(struct vring_avail)    + \
374                                                  (QUEUE_SIZE * sizeof(uint16_t)));
375                 
376                 // round up to next page boundary.
377                 virtio->queue.ring_used_addr = (virtio->queue.ring_used_addr + 0xfff) & ~0xfff;
378
379                 if (guest_pa_to_host_va(dev->vm, virtio->queue.ring_desc_addr, (addr_t *)&(virtio->queue.desc)) == -1) {
380                     PrintError("Could not translate ring descriptor address\n");
381                     return -1;
382                 }
383
384
385                 if (guest_pa_to_host_va(dev->vm, virtio->queue.ring_avail_addr, (addr_t *)&(virtio->queue.avail)) == -1) {
386                     PrintError("Could not translate ring available address\n");
387                     return -1;
388                 }
389
390
391                 if (guest_pa_to_host_va(dev->vm, virtio->queue.ring_used_addr, (addr_t *)&(virtio->queue.used)) == -1) {
392                     PrintError("Could not translate ring used address\n");
393                     return -1;
394                 }
395
396                 PrintDebug("RingDesc_addr=%p, Avail_addr=%p, Used_addr=%p\n",
397                            (void *)(virtio->queue.ring_desc_addr),
398                            (void *)(virtio->queue.ring_avail_addr),
399                            (void *)(virtio->queue.ring_used_addr));
400
401                 PrintDebug("RingDesc=%p, Avail=%p, Used=%p\n", 
402                            virtio->queue.desc, virtio->queue.avail, virtio->queue.used);
403
404             } else {
405                 PrintError("Illegal write length for page frame number\n");
406                 return -1;
407             }
408             break;
409         case VRING_Q_SEL_PORT:
410             virtio->virtio_cfg.vring_queue_selector = *(uint16_t *)src;
411
412             if (virtio->virtio_cfg.vring_queue_selector != 0) {
413                 PrintError("Virtio Block device only uses 1 queue, selected %d\n", 
414                            virtio->virtio_cfg.vring_queue_selector);
415                 return -1;
416             }
417
418             break;
419         case VRING_Q_NOTIFY_PORT:
420             PrintDebug("Handling Kick\n");
421             if (handle_kick(dev) == -1) {
422                 PrintError("Could not handle Block Notification\n");
423                 return -1;
424             }
425             break;
426         case VIRTIO_STATUS_PORT:
427             virtio->virtio_cfg.status = *(uint8_t *)src;
428
429             if (virtio->virtio_cfg.status == 0) {
430                 PrintDebug("Resetting device\n");
431                 virtio_reset(dev);
432             }
433
434             break;
435
436         case VIRTIO_ISR_PORT:
437             virtio->virtio_cfg.pci_isr = *(uint8_t *)src;
438             break;
439         default:
440             return -1;
441             break;
442     }
443
444     return length;
445 }
446
447
448 static int virtio_io_read(uint16_t port, void * dst, uint_t length, struct vm_device * dev) {
449     struct virtio_blk_state * virtio = (struct virtio_blk_state *)dev->private_data;
450     int port_idx = port % virtio->io_range_size;
451
452
453     PrintDebug("VIRTIO BLOCK Read  for port %d (index =%d), length=%d\n", 
454                port, port_idx, length);
455
456     switch (port_idx) {
457         case HOST_FEATURES_PORT:
458             if (length != 4) {
459                 PrintError("Illegal read length for host features\n");
460                 return -1;
461             }
462
463             *(uint32_t *)dst = virtio->virtio_cfg.host_features;
464         
465             break;
466         case VRING_PG_NUM_PORT:
467             if (length != 4) {
468                 PrintError("Illegal read length for page frame number\n");
469                 return -1;
470             }
471
472             *(uint32_t *)dst = virtio->queue.pfn;
473
474             break;
475         case VRING_SIZE_PORT:
476             if (length != 2) {
477                 PrintError("Illegal read length for vring size\n");
478                 return -1;
479             }
480                 
481             *(uint16_t *)dst = virtio->queue.queue_size;
482
483             break;
484
485         case VIRTIO_STATUS_PORT:
486             if (length != 1) {
487                 PrintError("Illegal read length for status\n");
488                 return -1;
489             }
490
491             *(uint8_t *)dst = virtio->virtio_cfg.status;
492             break;
493
494         case VIRTIO_ISR_PORT:
495             *(uint8_t *)dst = virtio->virtio_cfg.pci_isr;
496             virtio->virtio_cfg.pci_isr = 0;
497             v3_pci_lower_irq(virtio->pci_bus, 0, virtio->pci_dev);
498             break;
499
500         default:
501             if ( (port_idx >= sizeof(struct virtio_config)) && 
502                  (port_idx < (sizeof(struct virtio_config) + sizeof(struct blk_config))) ) {
503                 int cfg_offset = port_idx - sizeof(struct virtio_config);
504                 uint8_t * cfg_ptr = (uint8_t *)&(virtio->block_cfg);
505
506                 memcpy(dst, cfg_ptr + cfg_offset, length);
507                 
508             } else {
509                 PrintError("Read of Unhandled Virtio Read\n");
510                 return -1;
511             }
512           
513             break;
514     }
515
516     return length;
517 }
518
519
520
521
522 static struct v3_device_ops dev_ops = {
523     .free = virtio_free,
524     .reset = NULL,
525     .start = NULL,
526     .stop = NULL,
527 };
528
529
530
531
532 int v3_virtio_register_cdrom(struct vm_device * dev, struct v3_cd_ops * ops, void * private_data) {
533     struct virtio_blk_state * virtio = (struct virtio_blk_state *)dev->private_data;
534     
535     virtio->block_type = BLOCK_CDROM;
536     virtio->cd_ops = ops;
537     virtio->backend_data = private_data;
538
539     virtio->block_cfg.capacity = ops->get_capacity(private_data);
540
541     return 0;
542 }
543
544
545 int v3_virtio_register_harddisk(struct vm_device * dev, struct v3_hd_ops * ops, void * private_data) {
546     struct virtio_blk_state * virtio = (struct virtio_blk_state *)dev->private_data;
547
548     virtio->block_type = BLOCK_DISK;
549     virtio->hd_ops = ops;
550     virtio->backend_data = private_data;
551
552     virtio->block_cfg.capacity = ops->get_capacity(private_data);
553
554     PrintDebug("Virtio Capacity = %d -- 0x%p\n", (int)(virtio->block_cfg.capacity), 
555         (void *)(addr_t)(virtio->block_cfg.capacity));
556
557     return 0;
558 }
559
560
561
562 static int virtio_init(struct guest_info * vm, void * cfg_data) {
563     struct vm_device * pci_bus = v3_find_dev(vm, (char *)cfg_data);
564     struct virtio_blk_state * virtio_state = NULL;
565     struct pci_device * pci_dev = NULL;
566
567     PrintDebug("Initializing VIRTIO Block device\n");
568
569     if (pci_bus == NULL) {
570         PrintError("VirtIO devices require a PCI Bus");
571         return -1;
572     }
573
574     
575     virtio_state  = (struct virtio_blk_state *)V3_Malloc(sizeof(struct virtio_blk_state));
576     memset(virtio_state, 0, sizeof(struct virtio_blk_state));
577
578
579     struct vm_device * dev = v3_allocate_device("LNX_VIRTIO_BLK", &dev_ops, virtio_state);
580     if (v3_attach_device(vm, dev) == -1) {
581         PrintError("Could not attach device %s\n", "LNX_VIRTIO_BLK");
582         return -1;
583     }
584
585
586     // PCI initialization
587     {
588         struct v3_pci_bar bars[6];
589         int num_ports = sizeof(struct virtio_config) + sizeof(struct blk_config);
590         int tmp_ports = num_ports;
591         int i;
592
593
594
595         // This gets the number of ports, rounded up to a power of 2
596         virtio_state->io_range_size = 1; // must be a power of 2
597
598         while (tmp_ports > 0) {
599             tmp_ports >>= 1;
600             virtio_state->io_range_size <<= 1;
601         }
602         
603         // this is to account for any low order bits being set in num_ports
604         // if there are none, then num_ports was already a power of 2 so we shift right to reset it
605         if ((num_ports & ((virtio_state->io_range_size >> 1) - 1)) == 0) {
606             virtio_state->io_range_size >>= 1;
607         }
608
609
610         for (i = 0; i < 6; i++) {
611             bars[i].type = PCI_BAR_NONE;
612         }
613
614         bars[0].type = PCI_BAR_IO;
615         bars[0].default_base_port = -1;
616         bars[0].num_ports = virtio_state->io_range_size;
617
618         bars[0].io_read = virtio_io_read;
619         bars[0].io_write = virtio_io_write;
620
621         pci_dev = v3_pci_register_device(pci_bus, PCI_STD_DEVICE, 
622                                          0, PCI_AUTO_DEV_NUM, 0,
623                                          "LNX_VIRTIO_BLK", bars,
624                                          NULL, NULL, NULL, dev);
625
626         if (!pci_dev) {
627             PrintError("Could not register PCI Device\n");
628             return -1;
629         }
630         
631         pci_dev->config_header.vendor_id = VIRTIO_VENDOR_ID;
632         pci_dev->config_header.subsystem_vendor_id = VIRTIO_SUBVENDOR_ID;
633         
634
635         pci_dev->config_header.device_id = VIRTIO_BLOCK_DEV_ID;
636         pci_dev->config_header.class = PCI_CLASS_STORAGE;
637         pci_dev->config_header.subclass = PCI_STORAGE_SUBCLASS_OTHER;
638     
639         pci_dev->config_header.subsystem_id = VIRTIO_BLOCK_SUBDEVICE_ID;
640
641
642         pci_dev->config_header.intr_pin = 1;
643
644         pci_dev->config_header.max_latency = 1; // ?? (qemu does it...)
645
646
647         virtio_state->pci_dev = pci_dev;
648         virtio_state->pci_bus = pci_bus;
649     }
650
651     /* Block configuration */
652     virtio_state->virtio_cfg.host_features = VIRTIO_SEG_MAX;
653     virtio_state->block_cfg.max_seg = QUEUE_SIZE - 2;
654
655     // Virtio Block only uses one queue
656     virtio_state->queue.queue_size = QUEUE_SIZE;
657
658     virtio_reset(dev);
659
660
661
662     virtio_state->backend_data = NULL;
663     virtio_state->block_type = BLOCK_NONE;
664     virtio_state->hd_ops = NULL;
665
666     return 0;
667 }
668
669
670 device_register("LNX_VIRTIO_BLK", virtio_init)