Skip to contentSkip to conversation

Support for booting from virtio disks

PATCH Superseded Gleb Natapov 3 participants 4 messages May 9, 2010 – May 10, 2010

Subsystems (2)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Support for booting from virtio disks

This patch adds native support for booting from virtio disks to Seabios.

Makefile +2 -1
index 327a1bf..d0b8881 100644
@@ -14,7 +14,8 @@ OUT=out/
 SRCBOTH=misc.c pmm.c stacks.c output.c util.c block.c floppy.c ata.c mouse.c \
         kbd.c pci.c serial.c clock.c pic.c cdrom.c ps2port.c smp.c resume.c \
         pnpbios.c pirtable.c vgahooks.c ramdisk.c pcibios.c blockcmd.c \
-        usb.c usb-uhci.c usb-ohci.c usb-ehci.c usb-hid.c usb-msc.c
+        usb.c usb-uhci.c usb-ohci.c usb-ehci.c usb-hid.c usb-msc.c \
+        virtio-ring.c virtio-pci.c virtio-blk.c
 SRC16=$(SRCBOTH) system.c disk.c apm.c font.c
 SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
       acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \
src/block.c +3 -0
index ddf441f..b6b1902 100644
@@ -11,6 +11,7 @@
 #include "util.h" // dprintf
 #include "ata.h" // process_ata_op
 #include "usb-msc.h" // process_usb_op
+#include "virtio-blk.h" // process_virtio_op
 
 struct drives_s Drives VAR16VISIBLE;
 
@@ -289,6 +290,8 @@ process_op(struct disk_op_s *op)
         return process_cdemu_op(op);
     case DTYPE_USB:
         return process_usb_op(op);
+    case DTYPE_VIRTIO:
+	return process_virtio_op(op);
     default:
         op->count = 0;
         return DISK_RET_EPARAM;
src/config.h +3 -0
index b101174..ad569c6 100644
@@ -136,6 +136,9 @@
 #define CONFIG_SUBMODEL_ID   0x00
 #define CONFIG_BIOS_REVISION 0x01
 
+// Support boot from virtio storage
+#define CONFIG_VIRTIO_BLK 1
+
 // Various memory addresses used by the code.
 #define BUILD_STACK_ADDR          0x7000
 #define BUILD_S3RESUME_STACK_ADDR 0x1000
src/disk.h +1 -0
index 0cd1b74..9e5b083 100644
@@ -197,6 +197,7 @@ struct drive_s {
 #define DTYPE_RAMDISK  0x04
 #define DTYPE_CDEMU    0x05
 #define DTYPE_USB      0x06
+#define DTYPE_VIRTIO   0x07
 
 #define MAXDESCSIZE 80
 
src/pci_ids.h +3 -0
index 1800f1d..e1cded2 100644
@@ -2605,3 +2605,6 @@
 #define PCI_DEVICE_ID_RME_DIGI32	0x9896
 #define PCI_DEVICE_ID_RME_DIGI32_PRO	0x9897
 #define PCI_DEVICE_ID_RME_DIGI32_8	0x9898
+
+#define PCI_VENDOR_ID_REDHAT_QUMRANET	0x1af4
+#define PCI_DEVICE_ID_VIRTIO_BLK	0x1001
src/post.c +2 -0
index 638b0f7..25535e2 100644
@@ -23,6 +23,7 @@
 #include "smbios.h" // smbios_init
 #include "paravirt.h" // qemu_cfg_port_probe
 #include "ps2port.h" // ps2port_setup
+#include "virtio-blk.h" // virtio_blk_setup
 
 void
 __set_irq(int vector, void *loc)
@@ -184,6 +185,7 @@ init_hw(void)
     floppy_setup();
     ata_setup();
     ramdisk_setup();
+    virtio_blk_setup();
 }
 
 // Main setup code.
src/virtio-blk.c new file +153 -0

153 lines not on this page · raw message

src/virtio-blk.h new file +40 -0
new file mode 100644
index 0000000..3369ea4
@@ -0,0 +1,40 @@
+#ifndef _VIRTIO_BLK_H
+#define _VIRTIO_BLK_H
+
+struct virtio_blk_config
+{
+    u64 capacity;
+    u32 size_max;
+    u32 seg_max;
+    u16 cylinders;
+    u8 heads;
+    u8 sectors;
+    u32 blk_size;
+    u8 physical_block_exp;
+    u8 alignment_offset;
+    u16 min_io_size;
+    u32 opt_io_size;
+} __attribute__((packed));
+
+/* These two define direction. */
+#define VIRTIO_BLK_T_IN		0
+#define VIRTIO_BLK_T_OUT	1
+
+/* This is the first element of the read scatter-gather list. */
+struct virtio_blk_outhdr {
+    /* VIRTIO_BLK_T* */
+    u32 type;
+    /* io priority. */
+    u32 ioprio;
+    /* Sector (ie. 512 byte offset) */
+    u64 sector;
+};
+
+#define VIRTIO_BLK_S_OK		0
+#define VIRTIO_BLK_S_IOERR	1
+#define VIRTIO_BLK_S_UNSUPP	2
+
+int process_virtio_op(struct disk_op_s *op);
+void virtio_blk_setup(void);
+
+#endif /* _VIRTIO_BLK_H */
src/virtio-pci.c new file +65 -0

65 lines not on this page · raw message

src/virtio-pci.h new file +97 -0

97 lines not on this page · raw message

src/virtio-ring.c new file +152 -0

152 lines not on this page · raw message

src/virtio-ring.h new file +125 -0

125 lines not on this page · raw message

--
Gleb.

#1 lore raw

On Sun, May 9, 2010 at 4:23 PM, Gleb Natapov <[email protected]> wrote:
Neat! I believe SeaBIOS will see virtio-blk devices as harddisks and not attempt to boot ISOs? Many existing OS installers probably cannot boot from virtio-blk, but in the longer term folks might like to get rid of ATAPI CD-ROMs in their VMs.

Quoted 7 lines

+        char *desc = malloc_tmphigh(MAXDESCSIZE);
+        struct virtiodrive_s *vdrive_g = malloc_fseg(sizeof(*vdrive_g));
+        struct vring_virtqueue *vq = malloc_low(sizeof(*vq));
+        if (!vdrive_g || !desc || !vq) {
+            warn_noalloc();
+            return;
+        }

[...]

Quoted 6 lines

+        if (vp_find_vq(ioaddr, 0, vdrive_g->vq) < 0 ) {
+            free(vdrive_g);
+            dprintf(1, "fail to find vq for virtio-blk %x:%x\n",
+                    pci_bdf_to_bus (bdf), pci_bdf_to_dev(bdf));
+            continue;
+        }

Are desc, vdrive_g, and/or vq getting leaked on error?

Stefan

#2 lore raw
Quoted 6 lines · Stefan Hajnoczi

On Sun, May 9, 2010 at 4:23 PM, Gleb Natapov <[email protected]> wrote:
Neat! I believe SeaBIOS will see virtio-blk devices as harddisks and not attempt to boot ISOs? Many existing OS installers probably cannot boot from virtio-blk, but in the longer term folks might like to get rid of ATAPI CD-ROMs in their VMs.

The patch assumes that all virtio-blk devices are disks and it can boot from any of virtio-blk disks if there is more then one. I am not sure CDROM can be attached via virtio-blk interface.

Quoted 8 lines
Quoted 7 lines

+        char *desc = malloc_tmphigh(MAXDESCSIZE);
+        struct virtiodrive_s *vdrive_g = malloc_fseg(sizeof(*vdrive_g));
+        struct vring_virtqueue *vq = malloc_low(sizeof(*vq));
+        if (!vdrive_g || !desc || !vq) {
+            warn_noalloc();
+            return;
+        }

[...]

Quoted 9 lines
Quoted 6 lines

+        if (vp_find_vq(ioaddr, 0, vdrive_g->vq) < 0 ) {
+            free(vdrive_g);
+            dprintf(1, "fail to find vq for virtio-blk %x:%x\n",
+                    pci_bdf_to_bus (bdf), pci_bdf_to_dev(bdf));
+            continue;
+        }

Are desc, vdrive_g, and/or vq getting leaked on error?

vdrive_g is freed, but desc and vq are leaked. Will fix. Thanks!

--
Gleb.

#3 lore raw
In reply to Gleb Natapov
Quoted 1 line · Gleb Natapov

This patch adds native support for booting from virtio disks to Seabios.

Thanks Gleb - it looks good to me.

One thing I noticed - the virtio-pci.c file is missing a license statement and virtio-ring.c states GPL instead of LGPL.

-Kevin