Add a function that returns an error if any ram_list block represents volatile memory.
Signed-off-by: Steve Sistare <steven.sist...@oracle.com> --- include/exec/memory.h | 8 ++++++++ softmmu/memory.c | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/exec/memory.h b/include/exec/memory.h index c3d417d..0e6d364 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -2925,6 +2925,14 @@ bool ram_block_discard_is_disabled(void); */ bool ram_block_discard_is_required(void); +/** + * qemu_ram_check_volatile: return 1 if any memory regions are writable and not + * backed by shared memory, else return 0. + * + * @errp: returned error message identifying the first volatile region found. + */ +int qemu_check_ram_volatile(Error **errp); + #endif #endif diff --git a/softmmu/memory.c b/softmmu/memory.c index bfedaf9..e143692 100644 --- a/softmmu/memory.c +++ b/softmmu/memory.c @@ -2809,6 +2809,32 @@ void memory_global_dirty_log_stop(void) memory_global_dirty_log_do_stop(); } +static int check_volatile(RAMBlock *rb, void *opaque) +{ + MemoryRegion *mr = rb->mr; + + if (mr && + memory_region_is_ram(mr) && + !memory_region_is_ram_device(mr) && + !memory_region_is_rom(mr) && + (rb->fd == -1 || !qemu_ram_is_shared(rb))) { + *(const char **)opaque = memory_region_name(mr); + return -1; + } + return 0; +} + +int qemu_check_ram_volatile(Error **errp) +{ + char *name; + + if (qemu_ram_foreach_block(check_volatile, &name)) { + error_setg(errp, "Memory region %s is volatile", name); + return -1; + } + return 0; +} + static void listener_add_address_space(MemoryListener *listener, AddressSpace *as) { -- 1.8.3.1