@@ -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
@@ -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);
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 <david@redhat.com> --- include/exec/memory.h | 17 +++++++++++++++++ memory.c | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+)