From 98e753a6e51b255d474c4db5e7af8b01633b6a4c Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Tue, 25 Apr 2017 17:37:50 +0200 Subject: pc/fwcfg: unbreak migration from qemu-2.5 and qemu-2.6 during firmware boot Since 2.7 commit (b2a575a Add optionrom compatible with fw_cfg DMA version) regressed migration during firmware exection time by abusing fwcfg.dma_enabled property to decide loading dma version of option rom AND by mistake disabling DMA for 2.6 and earlier globally instead of only for option rom. so 2.6 machine type guest is broken when it already runs firmware in DMA mode but migrated to qemu-2.7(pc-2.6) at that time; a) qemu-2.6:pc2.6 (fwcfg.dma=on,firmware=dma,oprom=ioport) b) qemu-2.7:pc2.6 (fwcfg.dma=off,firmware=ioport,oprom=ioport) to: a b from a OK FAIL b OK OK So we currently have broken forward migration from qemu-2.6 to qemu-2.[789] that however could be fixed for 2.10 by re-enabling DMA for 2.[56] machine types and allowing dma capable option rom only since 2.7. As result qemu should end up with: c) qemu-2.10:pc2.6 (fwcfg.dma=on,firmware=dma,oprom=ioport) to: a b c from a OK FAIL OK b OK OK OK c OK FAIL OK where forward migration from qemu-2.6 to qemu-2.10 should work again leaving only qemu-2.[789]:pc-2.6 broken. Reported-by: Eduardo Habkost Analyzed-by: Laszlo Ersek Signed-off-by: Igor Mammedov Reviewed-by: Laszlo Ersek Reviewed-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'hw/i386/pc.c') diff --git a/hw/i386/pc.c b/hw/i386/pc.c index f3b372a18f..8063241140 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1047,12 +1047,10 @@ static void load_linux(PCMachineState *pcms, fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size); fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size); - if (fw_cfg_dma_enabled(fw_cfg)) { + option_rom[nb_option_roms].bootindex = 0; + option_rom[nb_option_roms].name = "linuxboot.bin"; + if (pcmc->linuxboot_dma_enabled && fw_cfg_dma_enabled(fw_cfg)) { option_rom[nb_option_roms].name = "linuxboot_dma.bin"; - option_rom[nb_option_roms].bootindex = 0; - } else { - option_rom[nb_option_roms].name = "linuxboot.bin"; - option_rom[nb_option_roms].bootindex = 0; } nb_option_roms++; } @@ -2321,6 +2319,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) * to be used at the moment, 32K should be enough for a while. */ pcmc->acpi_data_size = 0x20000 + 0x8000; pcmc->save_tsc_khz = true; + pcmc->linuxboot_dma_enabled = true; mc->get_hotplug_handler = pc_get_hotpug_handler; mc->cpu_index_to_socket_id = pc_cpu_index_to_socket_id; mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids; -- cgit v1.2.3