This patch aimed to avoid problem with uninitialized virtio-blk and virtio-scsi boot devices. Currently, 12 KiB of memory is allocated for each virtio-blk/scsi, so no more than about 10 devices can be initialized. If the device is not initialized, we cannot boot from it. So, if we have more than 10 devices, we can't boot from any of the following (11, 12, etc.). We can initialize only bootable devices, i.e. listed in boot order list, that this patch does.
Alexey Kirillov (1): virtio: do not init non-bootable devices
docs/Runtime_config.md | 1 + src/hw/virtio-blk.c | 10 ++++++++++ src/hw/virtio-scsi.c | 10 ++++++++++ 3 files changed, 21 insertions(+)
Because initializing a virtio-blk or virtio-scsi device requires a large amount of memory, you cannot create more than about 10 virtio devices. Since initialization is required for booting from media, we will not initialize those devices that are not in the boot order list.
Signed-off-by: Alexey Kirillov lekiravi@yandex-team.ru --- docs/Runtime_config.md | 1 + src/hw/virtio-blk.c | 10 ++++++++++ src/hw/virtio-scsi.c | 10 ++++++++++ 3 files changed, 21 insertions(+)
diff --git a/docs/Runtime_config.md b/docs/Runtime_config.md index 6747e2a..08f6e66 100644 --- a/docs/Runtime_config.md +++ b/docs/Runtime_config.md @@ -191,3 +191,4 @@ There are several additional configuration options available in the | threads | By default, SeaBIOS will parallelize hardware initialization during bootup to reduce boot time. Multiple hardware devices can be initialized in parallel between vga initialization and option rom initialization. One can set this file to a value of zero to force hardware initialization to run serially. Alternatively, one can set this file to 2 to enable early hardware initialization that runs in parallel with vga, option rom initialization, and the boot menu. | sdcard* | One may create one or more files with an "sdcard" prefix (eg, "etc/sdcard0") with the physical memory address of an SDHCI controller (one memory address per file). This may be useful for SDHCI controllers that do not appear as PCI devices, but are mapped to a consistent memory address. If this option is used then SeaBIOS will not scan for PCI SHDCI controllers. | usb-time-sigatt | The USB2 specification requires devices to signal that they are attached within 100ms of the USB port being powered on. Some USB devices are known to require more time. Prior to receiving an attachment signal there is no way to know if a USB port is empty or if it has a device attached. One may specify an amount of time here (in milliseconds, default 100) to wait for a USB device attachment signal. Increasing this value will also increase the overall machine bootup time. +| skip-non-bootable-virtio | If this item presented, initialization of non-bootable (i.e. not presented in bootorder) virtio-blk and virtio-scsi will be skipped. diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c index 3e615b2..2112112 100644 --- a/src/hw/virtio-blk.c +++ b/src/hw/virtio-blk.c @@ -15,6 +15,7 @@ #include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_DEVICE_ID_VIRTIO_BLK #include "pci_regs.h" // PCI_VENDOR_ID +#include "romfile.h" // romfile_find #include "stacks.h" // run_thread #include "std/disk.h" // DISK_RET_SUCCESS #include "string.h" // memset @@ -196,6 +197,8 @@ fail: void virtio_blk_setup(void) { + u8 skip_nonbootable = romfile_find("etc/skip-non-bootable-virtio") != NULL; + ASSERT32FLAT(); if (! CONFIG_VIRTIO_BLK) return; @@ -208,6 +211,13 @@ virtio_blk_setup(void) (pci->device != PCI_DEVICE_ID_VIRTIO_BLK_09 && pci->device != PCI_DEVICE_ID_VIRTIO_BLK_10)) continue; + + if (skip_nonbootable && bootprio_find_pci_device(pci) == -1) { + dprintf(1, "skipping init of a non-bootable virtio-blk at %pP\n", + pci); + continue; + } + run_thread(init_virtio_blk, pci); } } diff --git a/src/hw/virtio-scsi.c b/src/hw/virtio-scsi.c index e1e2f5d..70dfaa2 100644 --- a/src/hw/virtio-scsi.c +++ b/src/hw/virtio-scsi.c @@ -15,6 +15,7 @@ #include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_DEVICE_ID_VIRTIO_BLK #include "pci_regs.h" // PCI_VENDOR_ID +#include "romfile.h" // romfile_find #include "stacks.h" // run_thread #include "std/disk.h" // DISK_RET_SUCCESS #include "string.h" // memset @@ -205,6 +206,8 @@ fail: void virtio_scsi_setup(void) { + u8 skip_nonbootable = romfile_find("etc/skip-non-bootable-virtio") != NULL; + ASSERT32FLAT(); if (! CONFIG_VIRTIO_SCSI) return; @@ -217,6 +220,13 @@ virtio_scsi_setup(void) (pci->device != PCI_DEVICE_ID_VIRTIO_SCSI_09 && pci->device != PCI_DEVICE_ID_VIRTIO_SCSI_10)) continue; + + if (skip_nonbootable && bootprio_find_pci_device(pci) == -1) { + dprintf(1, "skipping init of a non-bootable virtio-scsi at %pP\n", + pci); + continue; + } + run_thread(init_virtio_scsi, pci); } }
Hi,
- u8 skip_nonbootable = romfile_find("etc/skip-non-bootable-virtio") != NULL;
There is no need for a new config file. qemu can place a HALT entry into the boot order file (qemu -boot strict=on). seabios will stop searching for boot devices when it discovers a HALT entry, so any device with a lower priority will not be considered for boot. Typically that are devices with a default priority because they didn't got a bootindex assigned. You can also use that to skip initialization altogether.
cheers, Gerd
Hi!
Yes, it's a good solution. However, it may cause the following problem: user wants to use a large number of virtio-blk/virtio-scsi devices, but not to use strict boot. For example, to boot over the network or IDE CDROM by default when other options fail.
If we use HALT, that user will not be able to boot from any and all devices that are not in the boot order. But we wanted only to avoid initializing virtio-blk/scsi specifically (at least for now).
What do you think?
-- Alexey Kirillov Yandex.Cloud
On Fri, Dec 20, 2019 at 02:22:37PM +0300, Alexey Kirillov wrote:
Hi!
Yes, it's a good solution. However, it may cause the following problem: user wants to use a large number of virtio-blk/virtio-scsi devices, but not to use strict boot. For example, to boot over the network or IDE CDROM by default when other options fail.
You can make that work by assigning a boot index to every device you might want boot from, i.e. 1 to disk, 2 to cdrom and 3 to nic. These three devices will then be tried even with strict=on.
If we use HALT, that user will not be able to boot from any and all devices that are not in the boot order. But we wanted only to avoid initializing virtio-blk/scsi specifically (at least for now).
Well, I think we will probably extend that to other devices, to reduce memory consumption and hardware initialization time. We might stop loading option roms for NICs without boot index for example, or extend that logic to ide/sata/nvme disks.
So I think a simple way to flip the switch for all these optimizations would be good. And that way being "use strict=on and and assign a bootindex to every device you might want boot from" looks good to me. This option exists for quite a while already, so we don't need new qemu options to turn it on, therefore it will work with older qemu versions too. And seabios has the freedom to skip initialization for every device which has no bootindex without breaking something, because it would never boot from such a device with strict=on.
cheers, Gerd