
Hi,
I am hitting an issue with the new bootflow when booting with UEFI from a virtio device on Qemu Arm.
It seems the device number computation in efiload_read_file() does not work in the general virtio case, where it will pick the virtio device number instead of the block device index. On Qemu arm virt machine, many virtio mmio devices are provisioned in the memory map and no assumption can be made on the number of the actual virtio device in use in the general case.
This is an extract of the output of `dm tree' on this platform, focused on the virtio device from which I would like to boot:
virtio 31 [ + ] virtio-mmio |-- virtio_mmio@a003e00 blk 0 [ + ] virtio-blk | |-- virtio-blk#31 partition 0 [ + ] blk_partition | | |-- virtio-blk#31:1 partition 1 [ + ] blk_partition | | `-- virtio-blk#31:2 bootdev 2 [ + ] virtio_bootdev | `-- virtio-blk#31.bootdev
In this extract the actual virtio device number is 31, as will be picked by efiload_read_file(), but the desired block device index is zero, as would be used with e.g. `ls virtio 0'.
This can be reproduced for example with Buildroot qemu_aarch64_ebbr_defconfig or qemu_arm_ebbr_defconfig and updating the U-Boot version to v2023.04. This was working properly with U-Boot versions up to v2023.01.
This seems to be very specific to virtio, as the numbers align much more nicely for e.g. USB mass storage or NVMe.
To help debugging, the following patch forces the device number to zero in the case of virtio, which allows to boot again with UEFI and virtio on Qemu Arm. Hopefully this should give a hint of what is going on.
I tried to create a fix by looking for the first child device of UCLASS_BLK, and use its devnum instead in the case of virtio. Sadly, I am not able to confirm if this is a proper fix as I am hitting other boot issues in the case of multiple boot devices of the same class it seems...
Vincent.
--- boot/bootmeth_efi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c index 6a97ac02ff5..e5b0d8614ff 100644 --- a/boot/bootmeth_efi.c +++ b/boot/bootmeth_efi.c @@ -117,7 +117,9 @@ static int efiload_read_file(struct blk_desc *desc, struct bootflow *bflow) * this can go away. */ media_dev = dev_get_parent(bflow->dev); - snprintf(devnum_str, sizeof(devnum_str), "%x", dev_seq(media_dev)); + snprintf(devnum_str, sizeof(devnum_str), "%x", + device_get_uclass_id(media_dev) == UCLASS_VIRTIO ? 0 : + dev_seq(media_dev));
strlcpy(dirname, bflow->fname, sizeof(dirname)); last_slash = strrchr(dirname, '/');