qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

exec/rom_reset: Free rom data during inmigrate skip

Commit 355477f8c73e9 skips rom reset when we're an incoming migration
so as not to overwrite shared ram in the ignore-shared migration
optimisation.
However, it's got an unexpected side effect that because it skips
freeing the ROM data, when rom_reset gets called later on, after
migration (e.g. during a reboot), the ROM does get reset to the original
file contents. Because of seabios/x86's weird reboot process
this confuses a reboot into hanging after a migration.

Fixes: 355477f8c73e9 ("migration: do not rom_reset() during incoming migration")
https://bugzilla.redhat.com/show_bug.cgi?id=1809380

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Dr. David Alan Gilbert and committed by
Paolo Bonzini
5073b5d3 67cf3f5c

+16 -9
+16 -9
hw/core/loader.c
··· 1119 1119 { 1120 1120 Rom *rom; 1121 1121 1122 - /* 1123 - * We don't need to fill in the RAM with ROM data because we'll fill 1124 - * the data in during the next incoming migration in all cases. Note 1125 - * that some of those RAMs can actually be modified by the guest on ARM 1126 - * so this is probably the only right thing to do here. 1127 - */ 1128 - if (runstate_check(RUN_STATE_INMIGRATE)) 1129 - return; 1130 - 1131 1122 QTAILQ_FOREACH(rom, &roms, next) { 1132 1123 if (rom->fw_file) { 1133 1124 continue; 1134 1125 } 1126 + /* 1127 + * We don't need to fill in the RAM with ROM data because we'll fill 1128 + * the data in during the next incoming migration in all cases. Note 1129 + * that some of those RAMs can actually be modified by the guest. 1130 + */ 1131 + if (runstate_check(RUN_STATE_INMIGRATE)) { 1132 + if (rom->data && rom->isrom) { 1133 + /* 1134 + * Free it so that a rom_reset after migration doesn't 1135 + * overwrite a potentially modified 'rom'. 1136 + */ 1137 + rom_free_data(rom); 1138 + } 1139 + continue; 1140 + } 1141 + 1135 1142 if (rom->data == NULL) { 1136 1143 continue; 1137 1144 }