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 (2): boot: Detect strict boot order (HALT record) in function virtio: Do not init non-bootable devices
src/boot.c | 5 +++++ src/hw/virtio-blk.c | 11 ++++++++++- src/hw/virtio-scsi.c | 11 ++++++++++- src/util.h | 1 + 4 files changed, 26 insertions(+), 2 deletions(-)
Introduce is_bootprio_strict(). We will reuse this function in the next commit.
Signed-off-by: Alexey Kirillov lekiravi@yandex-team.ru --- src/boot.c | 5 +++++ src/util.h | 1 + 2 files changed, 6 insertions(+)
diff --git a/src/boot.c b/src/boot.c index ea18194..e9b2cd0 100644 --- a/src/boot.c +++ b/src/boot.c @@ -295,6 +295,11 @@ find_prio(const char *glob) return -1; }
+u8 is_bootprio_strict() +{ + return find_prio("HALT") >= 0; +} + int bootprio_find_pci_device(struct pci_device *pci) { if (CONFIG_CSM) diff --git a/src/util.h b/src/util.h index b173fa8..566883c 100644 --- a/src/util.h +++ b/src/util.h @@ -27,6 +27,7 @@ void boot_add_cd(struct drive_s *drive_g, const char *desc, int prio); void boot_add_cbfs(void *data, const char *desc, int prio); void interactive_bootmenu(void); void bcv_prepboot(void); +u8 is_bootprio_strict(); struct pci_device; int bootprio_find_pci_device(struct pci_device *pci); int bootprio_find_scsi_device(struct pci_device *pci, int target, int lun);
Hi,
+u8 is_bootprio_strict() +{
- return find_prio("HALT") >= 0;
+}
./src/boot.c: In function 'is_bootprio_strict': ./src/boot.c:298:4: warning: old-style function definition [-Wold-style-definition]
Please fix. Otherwise the patches look good to me.
cheers, Gerd
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 --- src/hw/virtio-blk.c | 11 ++++++++++- src/hw/virtio-scsi.c | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c index 3e615b2..a5e28fc 100644 --- a/src/hw/virtio-blk.c +++ b/src/hw/virtio-blk.c @@ -18,7 +18,7 @@ #include "stacks.h" // run_thread #include "std/disk.h" // DISK_RET_SUCCESS #include "string.h" // memset -#include "util.h" // usleep +#include "util.h" // usleep, bootprio_find_pci_device, is_bootprio_strict #include "virtio-pci.h" #include "virtio-ring.h" #include "virtio-blk.h" @@ -196,6 +196,8 @@ fail: void virtio_blk_setup(void) { + u8 skip_nonbootable = is_bootprio_strict(); + ASSERT32FLAT(); if (! CONFIG_VIRTIO_BLK) return; @@ -208,6 +210,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) < 0) { + 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..a27bdc1 100644 --- a/src/hw/virtio-scsi.c +++ b/src/hw/virtio-scsi.c @@ -18,7 +18,7 @@ #include "stacks.h" // run_thread #include "std/disk.h" // DISK_RET_SUCCESS #include "string.h" // memset -#include "util.h" // usleep +#include "util.h" // usleep, bootprio_find_pci_device, is_bootprio_strict #include "virtio-pci.h" #include "virtio-ring.h" #include "virtio-scsi.h" @@ -205,6 +205,8 @@ fail: void virtio_scsi_setup(void) { + u8 skip_nonbootable = is_bootprio_strict(); + ASSERT32FLAT(); if (! CONFIG_VIRTIO_SCSI) return; @@ -217,6 +219,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) < 0) { + dprintf(1, "skipping init of a non-bootable virtio-scsi at %pP\n", + pci); + continue; + } + run_thread(init_virtio_scsi, pci); } }