On 14/09/2016 09:55, Herongguang (Stephen) wrote: > Hi, > We found a problem that when a redhat 6 VM reboots (in grub countdown > UI), migrating this VM will result in VM’s memory difference between > source and destination side. The difference always resides in GPA > 0xA0000~0xC0000, i.e. SMRAM area. > > Occasionally this result in VM instruction emulation error in > destination side. > > After some digging, I think this is because in migration code, in > migration_bitmap_sync(), only memory slots in address space > address_space_memory’s dirty bitmap fetched from kvm-kmod, while SMRAM > memory slot, in address space smram_address_space’s dirty bitmap not > fetched from kvm-kmod, thus modifications in SMRAM in source side are > not sent to destination side. > > I tried following patch, and this phenomenon does not happen anymore. Do > you think this patch is OK or do you have better idea? Thanks.
Nice caatch! I think the right solution here is to sync all RAM memory regions instead of the address spaces. You can do that by putting a notifier in MemoryRegion; register the notifier in all the RAM creation functions (basically after every mr->ram=true or mr->rom_device=true), and unregister it in memory_region_destructor_ram. Thanks, Paolo > diff --git a/migration/ram.c b/migration/ram.c > index a3d70c4..1cc4360 100644 > --- a/migration/ram.c > +++ b/migration/ram.c > @@ -607,6 +607,8 @@ static void migration_bitmap_sync_init(void) > iterations_prev = 0; > } > > +extern AddressSpace smram_address_space; > + > static void migration_bitmap_sync(void) > { > RAMBlock *block; > @@ -627,6 +629,7 @@ static void migration_bitmap_sync(void) > > trace_migration_bitmap_sync_start(); > address_space_sync_dirty_bitmap(&address_space_memory); > + address_space_sync_dirty_bitmap(&smram_address_space); > > qemu_mutex_lock(&migration_bitmap_mutex); > rcu_read_lock(); > diff --git a/target-i386/kvm.c b/target-i386/kvm.c > index d1a25c5..b98fe22 100644 > --- a/target-i386/kvm.c > +++ b/target-i386/kvm.c > @@ -1111,7 +1111,7 @@ static int kvm_get_supported_msrs(KVMState *s) > > static Notifier smram_machine_done; > static KVMMemoryListener smram_listener; > -static AddressSpace smram_address_space; > +AddressSpace smram_address_space; > static MemoryRegion smram_as_root; > static MemoryRegion smram_as_mem; > > >