0

I am currently trying to boot a QEMU VM with a virtio-blk hard disk and I am failing. I cannot seem to get the kernel to recognize the virtio device.

I am on a linux-6.1.97 source tree and bootstrapped the configuration using the one provided by Firecracker. At this point I enabled every configuration option which has VIRTIO in its name but the kernel still does not recognize any virtio device that QEMU supposedly exposed. (My rootfs is EXT4 and I have the required kernel configurations enabled)

Essentially the problem boils down to this:

[    0.083797] Please append a correct "root=" boot option; here are the available partitions:
[    0.084323] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

(The kernel cannot even find the device. The mentioned kernel configuration options CONFIG_VIRTIO_BLK=y and CONFIG_VIRTIO_PCI=y are enabled.)

Here is my QEMU command line:

exec qemu-system-x86_64 \
    -enable-kvm \
    -cpu host \
    -m 512 -smp 2 \
    -kernel bzImage \
    -append "console=ttyS0 reboot=t panic=0 root=/dev/vda" \
    -nodefaults -no-user-config -nographic \
    -serial stdio
    -no-reboot \
    -drive file=rootfs.img,format=raw,media=disk,if=virtio

Does anyone have an idea what might still be missing?

Edit: Here is the list of all configs enabled related to VIRTIO:

$ grep VIRTIO .config
CONFIG_BLK_MQ_VIRTIO=y
CONFIG_VIRTIO_VSOCKETS=y
CONFIG_VIRTIO_VSOCKETS_COMMON=y
CONFIG_VIRTIO_BLK=y
CONFIG_SCSI_VIRTIO=y
CONFIG_VIRTIO_NET=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_VIRTIO_ANCHOR=y
CONFIG_VIRTIO=y
CONFIG_VIRTIO_PCI_LIB=y
CONFIG_VIRTIO_PCI_LIB_LEGACY=y
CONFIG_VIRTIO_MENU=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_PCI_LEGACY=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_MEM=y
CONFIG_VIRTIO_INPUT=y
CONFIG_VIRTIO_MMIO=y
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
CONFIG_VIRTIO_IOMMU=y
CONFIG_RPMSG_VIRTIO=y
CONFIG_VIRTIO_FS=y

Edit2:

I did a little bit more digging and made some progress. When specifying -drive file=rootfs.img,format=raw,media=disk,if=virtio the disk will be on PCI and then the boot indeed works out when specifying CONFIG_VIRTIO_PCI. During experimentation I carelessly changed this, what I actually wanted was this:

    -drive id=test,file=rootfs.img,format=raw,if=none \
    -device virtio-blk-device,drive=test

Specifically this is running with the -M microvm QEMU machine target. And this indeed does not run the disk on PCI. Qemu adds the device to the kernel commandline, f.e. virtio_mmio.device=512@0xfeb00e00:12.

We can see the device being registered during boot:

[    0.041667] virtio-mmio: Registering device virtio-mmio.0 at 0xfeb00e00-0xfeb00fff, IRQ 12.

However eventually something fails prior to the message that no root fs could be found:

[    0.041667] virtio_blk virtio0: 1/0/0 default/read/poll queues
[    0.041667] virtio_blk: probe of virtio0 failed with error -22

I did a little bit of debugging, and found that this is caused by an error in virtio_mmio.c:vm_find_vqs, the call to request_irq (link) fails due to irq_to_desc returning NULL (link)

2
  • Can you post the output of grep VIRTIO .config? Your qemu-system-x86_64 command line works fine with my virtio-enabled kernel.
    – larsks
    Commented Jul 9 at 2:45
  • Thanks for looking into it. I edited the post.
    – milck
    Commented Jul 9 at 6:37

1 Answer 1

0

Eventually I found something which appears to be working fine:

A few things to watch out for:

  • the QEMU microvm machine accepts a bunch of options to disable legacy devices, i.e. rtc=off,pit=off,pic=off,isa-serial=off,x-option-rom=off. There were a couple of issues with certain argument subsets where QEMU would not append the virtio-mmio device to the kernel command line for some reason.
  • if you would like to enable pit=off,pic=off, you need to also disable ACPI via kernel command line, i.e. add acpi=off. Additionally you also need to enable CONFIG_X86_MPPARSE, otherwise the local apic will not get configured correctly and the kernel will hang at some point.
  • for the microvm it is indeed unnecessary to enable CONFIG_VIRTIO_PCI because the machine does not have PCI lanes. Everything is handled via virtio-mmio.

In the end, the vanilla Firecracker config + CONFIG_X86_MPPARSE worked out:

qemu-system-x86_64 \
    -M microvm,x-option-roms=off,acpi=off,rtc=off,pit=off,pic=off \
    -enable-kvm \
    -cpu host \
    -m 512 -smp 2 \
    -kernel bzImage \
    -append "console=ttyS0 reboot=t panic=0 root=/dev/vda acpi=off" \
    -nodefaults -no-user-config -nographic \
    -serial stdio \
    -no-reboot \
    -drive id=test,file=rootfs.img,format=raw,if=none \
    -device virtio-blk-device,drive=test
2
  • In your question you're not using the microvm hardware; doing so dramatically changes the nature of the solution (e.g., there is no PCI controller so `VIRTIO_PCI`` isn't relevant, while it's required when you're using the default hardware).
    – larsks
    Commented Jul 9 at 13:55
  • Yes I did clarify that in the question, see the edits.
    – milck
    Commented Jul 9 at 15:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .