diff options
author | Igor Mammedov <imammedo@redhat.com> | 2017-04-25 17:37:50 +0200 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2017-05-10 22:04:23 +0300 |
commit | 98e753a6e51b255d474c4db5e7af8b01633b6a4c (patch) | |
tree | ed8ac7b99975f87421d8977188ba4d980d1e3fbd /hw/i386/pc.c | |
parent | 640601c7cb1b6b41d3e1a435b986266c2b71e9bc (diff) | |
download | qemu-98e753a6e51b255d474c4db5e7af8b01633b6a4c.zip qemu-98e753a6e51b255d474c4db5e7af8b01633b6a4c.tar.gz qemu-98e753a6e51b255d474c4db5e7af8b01633b6a4c.tar.bz2 |
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 <ehabkost@redhat.com>
Analyzed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/i386/pc.c')
-rw-r--r-- | hw/i386/pc.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c index f3b372a..8063241 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; |