During system reset, and only during system reset, QEMU updates the "bootorder" and "bios-geometry" entries in fw_cfg based on the contents of "fw_boot_order" and "fw_lchs". After the guest VM boots, the firmware (e.g., SeaBIOS) can read the boot order from fw_cfg and boot from the disk at the top of the list.
The reset handler fw_cfg_machine_reset() is invoked either implicitly during instance creation or explicitly by the user via HMP/QMP. However, users may attach or detach disks while the VM is in the prelaunch state. Because there is no implicit reset when transitioning from prelaunch to running, the "bootorder" and "bios-geometry" data in fw_cfg can become stale. As a result, the firmware may be unable to locate the correct disk to boot from. Here is an example that demonstrates the bug. 1. Create a QEMU instance with a virtio-scsi HBA and keep it in the prelaunch state. Use SeaBIOS rather than UEFI. -device virtio-scsi-pci,id=scsi0,num_queues=4 \ -S \ 2. First, attach the boot disk, then attach the secondary disk. (qemu) drive_add 0 file=boot.qcow2,if=none,id=drive0 (qemu) device_add scsi-hd,drive=drive0,bus=scsi0.0,channel=0,scsi-id=0,lun=1,bootindex=1 (qemu) drive_add 0 file=secondary.qcow2,if=none,id=drive1 (qemu) device_add scsi-hd,drive=drive1,bus=scsi0.0,channel=0,scsi-id=0,lun=2,bootindex=-1 3. Start the VM from the prelaunch state. Because the "bootorder" and "bios-geometry" data in fw_cfg is stale, SeaBIOS attempts to boot from the secondary disk only once and then stops. As a result, the VM fails to boot. One possible workaround is to require QEMU users to explicitly issue a system_reset before starting a guest VM from the prelaunch state, if any disks have been attached or detached. Another option is to address the issue in SeaBIOS. Nowadays, SeaBIOS attempts to boot from only a single disk. We could enhance SeaBIOS to try multiple disks in order until boot succeeds. Another option is to update "bootorder" and "bios-geometry" everywhere disks are attached or detached. This may require identifying the relevant functions across multiple device types, such as SCSI, NVMe, virtio-blk, and IDE. This commit fixes the issue in QEMU by ensuring that "bootorder" and "bios-geometry" are always updated when QEMU transitions from the prelaunch state to running. According to runstate_transitions_def[], RUN_STATE_PRELAUNCH is allowed to transition to four states. Only the transition to RUN_STATE_RUNNING requires updating "bootorder" and "bios-geometry". v1: https://lore.kernel.org/qemu-devel/[email protected] v1 -> v2: - Add new runstate tranisition notifier to track transition from prelaunch to running. Dongli Zhang (2) system/runstate: add runstate transition notifier hw/nvram/fw_cfg: update bootorder and bios-geometry before launching hw/nvram/fw_cfg.c | 31 +++++++++++++++++++++++++++++-- include/hw/nvram/fw_cfg.h | 1 + include/system/runstate.h | 8 ++++++++ system/runstate.c | 25 +++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 2 deletions(-) Thank you very much! Dongli Zhang
