We want to pass resizable memory regions to devices that can deal with them (and autoamtically resize them). Allow them to easily identify if a region can be resized and what the maximum size is.
Add both functions, adding qemu_ram_is_resizable() as a helper. Signed-off-by: David Hildenbrand <da...@redhat.com> --- include/exec/memory.h | 17 +++++++++++++++++ memory.c | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/include/exec/memory.h b/include/exec/memory.h index 9f02bb7830..dfedd88f13 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -395,6 +395,7 @@ struct MemoryRegion { void *opaque; MemoryRegion *container; Int128 size; + Int128 max_size; hwaddr addr; void (*destructor)(MemoryRegion *mr); uint64_t align; @@ -1180,6 +1181,13 @@ struct Object *memory_region_owner(MemoryRegion *mr); */ uint64_t memory_region_size(MemoryRegion *mr); +/** + * memory_region_max_size: get a memory region's maximum size. + * + * @mr: the memory region being queried. + */ +uint64_t memory_region_max_size(MemoryRegion *mr); + /** * memory_region_is_ram: check whether a memory region is random access * @@ -1471,6 +1479,15 @@ MemoryRegion *memory_region_from_host(void *ptr, ram_addr_t *offset); */ void *memory_region_get_ram_ptr(MemoryRegion *mr); +/** + * memory_region_is_resizable: check whether a memory region resizable + * + * Returns %true if a memory region is resizable. + * + * @mr: the memory region being queried + */ +bool memory_region_is_resizable(MemoryRegion *mr); + /* memory_region_ram_resize: Resize a RAM region. * * Only legal before guest might have detected the memory size: e.g. on diff --git a/memory.c b/memory.c index cb09a8ee59..5c62702618 100644 --- a/memory.c +++ b/memory.c @@ -1130,6 +1130,7 @@ static void memory_region_do_init(MemoryRegion *mr, if (size == UINT64_MAX) { mr->size = int128_2_64(); } + mr->max_size = mr->size; mr->name = g_strdup(name); mr->owner = owner; mr->ram_block = NULL; @@ -1540,6 +1541,10 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr, { Error *err = NULL; memory_region_init(mr, owner, name, size); + mr->max_size = int128_make64(max_size); + if (max_size == UINT64_MAX) { + mr->max_size = int128_2_64(); + } mr->ram = true; mr->terminates = true; mr->destructor = memory_region_destructor_ram; @@ -1779,6 +1784,14 @@ uint64_t memory_region_size(MemoryRegion *mr) return int128_get64(mr->size); } +uint64_t memory_region_max_size(MemoryRegion *mr) +{ + if (int128_eq(mr->max_size, int128_2_64())) { + return UINT64_MAX; + } + return int128_get64(mr->max_size); +} + const char *memory_region_name(const MemoryRegion *mr) { if (!mr->name) { @@ -2198,6 +2211,11 @@ ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr) return mr->ram_block ? mr->ram_block->offset : RAM_ADDR_INVALID; } +bool memory_region_is_resizable(MemoryRegion *mr) +{ + return mr->ram_block && qemu_ram_is_resizable(mr->ram_block); +} + void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp) { assert(mr->ram_block); -- 2.24.1