mirror of
https://github.com/mii443/qemu.git
synced 2025-12-03 11:08:25 +00:00
migration: discard non-migratable RAMBlocks
On the POWER9 processor, the XIVE interrupt controller can control interrupt sources using MMIO to trigger events, to EOI or to turn off the sources. Priority management and interrupt acknowledgment is also controlled by MMIO in the presenter sub-engine. These MMIO regions are exposed to guests in QEMU with a set of 'ram device' memory mappings, similarly to VFIO, and the VMAs are populated dynamically with the appropriate pages using a fault handler. But, these regions are an issue for migration. We need to discard the associated RAMBlocks from the RAM state on the source VM and let the destination VM rebuild the memory mappings on the new host in the post_load() operation just before resuming the system. To achieve this goal, the following introduces a new RAMBlock flag RAM_MIGRATABLE which is updated in the vmstate_register_ram() and vmstate_unregister_ram() routines. This flag is then used by the migration to identify RAMBlocks to discard on the source. Some checks are also performed on the destination to make sure nothing invalid was sent. This change impacts the boston, malta and jazz mips boards for which migration compatibility is broken. Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
This commit is contained in:
committed by
Juan Quintela
parent
f548222c24
commit
b895de5027
38
exec.c
38
exec.c
@@ -104,6 +104,9 @@ static MemoryRegion io_mem_unassigned;
|
||||
* (Set during postcopy)
|
||||
*/
|
||||
#define RAM_UF_ZEROPAGE (1 << 3)
|
||||
|
||||
/* RAM can be migrated */
|
||||
#define RAM_MIGRATABLE (1 << 4)
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_PAGE_BITS_VARY
|
||||
@@ -1838,6 +1841,21 @@ void qemu_ram_set_uf_zeroable(RAMBlock *rb)
|
||||
rb->flags |= RAM_UF_ZEROPAGE;
|
||||
}
|
||||
|
||||
bool qemu_ram_is_migratable(RAMBlock *rb)
|
||||
{
|
||||
return rb->flags & RAM_MIGRATABLE;
|
||||
}
|
||||
|
||||
void qemu_ram_set_migratable(RAMBlock *rb)
|
||||
{
|
||||
rb->flags |= RAM_MIGRATABLE;
|
||||
}
|
||||
|
||||
void qemu_ram_unset_migratable(RAMBlock *rb)
|
||||
{
|
||||
rb->flags &= ~RAM_MIGRATABLE;
|
||||
}
|
||||
|
||||
/* Called with iothread lock held. */
|
||||
void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev)
|
||||
{
|
||||
@@ -3893,6 +3911,26 @@ int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qemu_ram_foreach_migratable_block(RAMBlockIterFunc func, void *opaque)
|
||||
{
|
||||
RAMBlock *block;
|
||||
int ret = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
RAMBLOCK_FOREACH(block) {
|
||||
if (!qemu_ram_is_migratable(block)) {
|
||||
continue;
|
||||
}
|
||||
ret = func(block->idstr, block->host, block->offset,
|
||||
block->used_length, opaque);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unmap pages of memory from start to start+length such that
|
||||
* they a) read as 0, b) Trigger whatever fault mechanism
|
||||
|
||||
Reference in New Issue
Block a user