From e1a4e4208f4140c83c3742d1e606d8888d170424 Mon Sep 17 00:00:00 2001 From: Peter Maydell <peter.maydell@linaro.org> Date: Sat, 17 Feb 2018 17:02:55 -0500 Subject: [PATCH] pc: resizeable ROM blocks This makes ROM blocks resizeable. This infrastructure is required for other functionality we have queued. Backports commit aaf03019175949eda5087329448b8a0033b89479 from qemu --- include/qemu.h | 16 +++- qemu/aarch64.h | 3 + qemu/aarch64eb.h | 3 + qemu/arm.h | 3 + qemu/armeb.h | 3 + qemu/exec.c | 142 +++++++++++++++++++++++++++-------- qemu/header_gen.py | 3 + qemu/include/exec/memory.h | 26 +++++++ qemu/include/exec/ram_addr.h | 10 ++- qemu/m68k.h | 3 + qemu/memory.c | 19 +++++ qemu/mips.h | 3 + qemu/mips64.h | 3 + qemu/mips64el.h | 3 + qemu/mipsel.h | 3 + qemu/powerpc.h | 3 + qemu/sparc.h | 3 + qemu/sparc64.h | 3 + qemu/x86_64.h | 3 + 19 files changed, 217 insertions(+), 38 deletions(-) diff --git a/include/qemu.h b/include/qemu.h index 05ef07fb..cf4f0421 100644 --- a/include/qemu.h +++ b/include/qemu.h @@ -19,11 +19,14 @@ struct uc_struct; // This two struct is originally from qemu/include/exec/cpu-all.h // Temporarily moved here since there is circular inclusion. -typedef struct RAMBlock { +typedef struct RAMBlock RAMBlock; +struct RAMBlock { struct MemoryRegion *mr; uint8_t *host; ram_addr_t offset; - ram_addr_t length; + ram_addr_t used_length; + ram_addr_t max_length; + void (*resized)(const char*, uint64_t length, void *host); uint32_t flags; char idstr[256]; /* Reads can take either the iothread or the ramlist lock. @@ -31,7 +34,14 @@ typedef struct RAMBlock { */ QTAILQ_ENTRY(RAMBlock) next; int fd; -} RAMBlock; +}; + +static inline void *ramblock_ptr(RAMBlock *block, ram_addr_t offset) +{ + assert(offset < block->used_length); + assert(block->host); + return (char *)block->host + offset; +} typedef struct { MemoryRegion *mr; diff --git a/qemu/aarch64.h b/qemu/aarch64.h index eae340ed..e51f654a 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -2085,6 +2085,7 @@ #define memory_region_init_ram memory_region_init_ram_aarch64 #define memory_region_init_ram_ptr memory_region_init_ram_ptr_aarch64 #define memory_region_init_reservation memory_region_init_reservation_aarch64 +#define memory_region_init_resizeable_ram memory_region_init_resizeable_ram_aarch64 #define memory_region_is_iommu memory_region_is_iommu_aarch64 #define memory_region_is_logging memory_region_is_logging_aarch64 #define memory_region_is_mapped memory_region_is_mapped_aarch64 @@ -2434,11 +2435,13 @@ #define qemu_ram_addr_from_host_nofail qemu_ram_addr_from_host_nofail_aarch64 #define qemu_ram_alloc qemu_ram_alloc_aarch64 #define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_aarch64 +#define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_aarch64 #define qemu_ram_foreach_block qemu_ram_foreach_block_aarch64 #define qemu_ram_free qemu_ram_free_aarch64 #define qemu_ram_free_from_ptr qemu_ram_free_from_ptr_aarch64 #define qemu_ram_ptr_length qemu_ram_ptr_length_aarch64 #define qemu_ram_remap qemu_ram_remap_aarch64 +#define qemu_ram_resize qemu_ram_resize_aarch64 #define qemu_ram_setup_dump qemu_ram_setup_dump_aarch64 #define qemu_ram_unset_idstr qemu_ram_unset_idstr_aarch64 #define qemu_real_host_page_size qemu_real_host_page_size_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 3b004e73..c04abd4d 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -2085,6 +2085,7 @@ #define memory_region_init_ram memory_region_init_ram_aarch64eb #define memory_region_init_ram_ptr memory_region_init_ram_ptr_aarch64eb #define memory_region_init_reservation memory_region_init_reservation_aarch64eb +#define memory_region_init_resizeable_ram memory_region_init_resizeable_ram_aarch64eb #define memory_region_is_iommu memory_region_is_iommu_aarch64eb #define memory_region_is_logging memory_region_is_logging_aarch64eb #define memory_region_is_mapped memory_region_is_mapped_aarch64eb @@ -2434,11 +2435,13 @@ #define qemu_ram_addr_from_host_nofail qemu_ram_addr_from_host_nofail_aarch64eb #define qemu_ram_alloc qemu_ram_alloc_aarch64eb #define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_aarch64eb +#define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_aarch64eb #define qemu_ram_foreach_block qemu_ram_foreach_block_aarch64eb #define qemu_ram_free qemu_ram_free_aarch64eb #define qemu_ram_free_from_ptr qemu_ram_free_from_ptr_aarch64eb #define qemu_ram_ptr_length qemu_ram_ptr_length_aarch64eb #define qemu_ram_remap qemu_ram_remap_aarch64eb +#define qemu_ram_resize qemu_ram_resize_aarch64eb #define qemu_ram_setup_dump qemu_ram_setup_dump_aarch64eb #define qemu_ram_unset_idstr qemu_ram_unset_idstr_aarch64eb #define qemu_real_host_page_size qemu_real_host_page_size_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 3d358a3c..52fe98f4 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -2085,6 +2085,7 @@ #define memory_region_init_ram memory_region_init_ram_arm #define memory_region_init_ram_ptr memory_region_init_ram_ptr_arm #define memory_region_init_reservation memory_region_init_reservation_arm +#define memory_region_init_resizeable_ram memory_region_init_resizeable_ram_arm #define memory_region_is_iommu memory_region_is_iommu_arm #define memory_region_is_logging memory_region_is_logging_arm #define memory_region_is_mapped memory_region_is_mapped_arm @@ -2434,11 +2435,13 @@ #define qemu_ram_addr_from_host_nofail qemu_ram_addr_from_host_nofail_arm #define qemu_ram_alloc qemu_ram_alloc_arm #define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_arm +#define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_arm #define qemu_ram_foreach_block qemu_ram_foreach_block_arm #define qemu_ram_free qemu_ram_free_arm #define qemu_ram_free_from_ptr qemu_ram_free_from_ptr_arm #define qemu_ram_ptr_length qemu_ram_ptr_length_arm #define qemu_ram_remap qemu_ram_remap_arm +#define qemu_ram_resize qemu_ram_resize_arm #define qemu_ram_setup_dump qemu_ram_setup_dump_arm #define qemu_ram_unset_idstr qemu_ram_unset_idstr_arm #define qemu_real_host_page_size qemu_real_host_page_size_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index a47d0579..ba4ff239 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -2085,6 +2085,7 @@ #define memory_region_init_ram memory_region_init_ram_armeb #define memory_region_init_ram_ptr memory_region_init_ram_ptr_armeb #define memory_region_init_reservation memory_region_init_reservation_armeb +#define memory_region_init_resizeable_ram memory_region_init_resizeable_ram_armeb #define memory_region_is_iommu memory_region_is_iommu_armeb #define memory_region_is_logging memory_region_is_logging_armeb #define memory_region_is_mapped memory_region_is_mapped_armeb @@ -2434,11 +2435,13 @@ #define qemu_ram_addr_from_host_nofail qemu_ram_addr_from_host_nofail_armeb #define qemu_ram_alloc qemu_ram_alloc_armeb #define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_armeb +#define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_armeb #define qemu_ram_foreach_block qemu_ram_foreach_block_armeb #define qemu_ram_free qemu_ram_free_armeb #define qemu_ram_free_from_ptr qemu_ram_free_from_ptr_armeb #define qemu_ram_ptr_length qemu_ram_ptr_length_armeb #define qemu_ram_remap qemu_ram_remap_armeb +#define qemu_ram_resize qemu_ram_resize_armeb #define qemu_ram_setup_dump qemu_ram_setup_dump_armeb #define qemu_ram_unset_idstr qemu_ram_unset_idstr_armeb #define qemu_real_host_page_size qemu_real_host_page_size_armeb diff --git a/qemu/exec.c b/qemu/exec.c index c090198a..9e5af124 100644 --- a/qemu/exec.c +++ b/qemu/exec.c @@ -62,6 +62,11 @@ /* RAM is mmap-ed with MAP_SHARED */ #define RAM_SHARED (1 << 1) +/* Only a portion of RAM (used_length) is actually used, and migrated. + * This used_length size can change across reboots. + */ +#define RAM_RESIZEABLE (1 << 2) + #endif #if !defined(CONFIG_USER_ONLY) @@ -677,11 +682,11 @@ static RAMBlock *qemu_get_ram_block(struct uc_struct *uc, ram_addr_t addr) /* The list is protected by the iothread lock here. */ block = uc->ram_list.mru_block; - if (block && addr - block->offset < block->length) { + if (block && addr - block->offset < block->max_length) { goto found; } QTAILQ_FOREACH(block, &uc->ram_list.blocks, next) { - if (addr - block->offset < block->length) { + if (addr - block->offset < block->max_length) { goto found; } } @@ -706,7 +711,7 @@ static void tlb_reset_dirty_range_all(struct uc_struct* uc, block = qemu_get_ram_block(uc, start); assert(block == qemu_get_ram_block(uc, end - 1)); - start1 = (uintptr_t)block->host + (start - block->offset); + start1 = (uintptr_t)ramblock_ptr(block, start - block->offset); cpu_tlb_reset_dirty_all(uc, start1, length); } @@ -931,7 +936,7 @@ static ram_addr_t find_ram_offset(struct uc_struct *uc, ram_addr_t size) QTAILQ_FOREACH(block, &uc->ram_list.blocks, next) { ram_addr_t end, next = RAM_ADDR_MAX; - end = block->offset + block->length; + end = block->offset + block->max_length; QTAILQ_FOREACH(next_block, &uc->ram_list.blocks, next) { if (next_block->offset >= end) { @@ -959,7 +964,7 @@ ram_addr_t last_ram_offset(struct uc_struct *uc) ram_addr_t last = 0; QTAILQ_FOREACH(block, &uc->ram_list.blocks, next) - last = MAX(last, block->offset + block->length); + last = MAX(last, block->offset + block->max_length); return last; } @@ -995,6 +1000,50 @@ static int memory_try_enable_merging(void *addr, size_t len) return 0; } +/* Only legal before guest might have detected the memory size: e.g. on + * incoming migration, or right after reset. + * + * As memory core doesn't know how is memory accessed, it is up to + * resize callback to update device state and/or add assertions to detect + * misuse, if necessary. + */ +int qemu_ram_resize(struct uc_struct *uc, ram_addr_t base, ram_addr_t newsize, Error **errp) +{ + RAMBlock *block = find_ram_block(uc, base); + + assert(block); + + if (block->used_length == newsize) { + return 0; + } + + if (!(block->flags & RAM_RESIZEABLE)) { + error_setg_errno(errp, EINVAL, + "Length mismatch: %s: 0x" RAM_ADDR_FMT + " in != 0x" RAM_ADDR_FMT, block->idstr, + newsize, block->used_length); + return -EINVAL; + } + + if (block->max_length < newsize) { + error_setg_errno(errp, EINVAL, + "Length too large: %s: 0x" RAM_ADDR_FMT + " > 0x" RAM_ADDR_FMT, block->idstr, + newsize, block->max_length); + return -EINVAL; + } + + cpu_physical_memory_clear_dirty_range(uc, block->offset, block->used_length); + block->used_length = newsize; + cpu_physical_memory_set_dirty_range(uc, block->offset, block->used_length, + DIRTY_CLIENTS_ALL); + memory_region_set_size(block->mr, newsize); + if (block->resized) { + block->resized(block->idstr, newsize, block->host); + } + return 0; +} + static ram_addr_t ram_block_add(struct uc_struct *uc, RAMBlock *new_block, Error **errp) { RAMBlock *block; @@ -1002,23 +1051,23 @@ static ram_addr_t ram_block_add(struct uc_struct *uc, RAMBlock *new_block, Error old_ram_size = last_ram_offset(uc) >> TARGET_PAGE_BITS; - new_block->offset = find_ram_offset(uc, new_block->length); + new_block->offset = find_ram_offset(uc, new_block->max_length); if (!new_block->host) { - new_block->host = phys_mem_alloc(new_block->length, - &new_block->mr->align); + new_block->host = phys_mem_alloc(new_block->max_length, + &new_block->mr->align); if (!new_block->host) { error_setg_errno(errp, errno, - "cannot set up guest memory '%s'", - memory_region_name(new_block->mr)); + "cannot set up guest memory '%s'", + memory_region_name(new_block->mr)); return -1; } - memory_try_enable_merging(new_block->host, new_block->length); + memory_try_enable_merging(new_block->host, new_block->max_length); } /* Keep the list sorted from biggest to smallest block. */ QTAILQ_FOREACH(block, &uc->ram_list.blocks, next) { - if (block->length < new_block->length) { + if (block->max_length < new_block->max_length) { break; } } @@ -1042,36 +1091,48 @@ static ram_addr_t ram_block_add(struct uc_struct *uc, RAMBlock *new_block, Error } } cpu_physical_memory_set_dirty_range(uc, new_block->offset, - new_block->length, + new_block->used_length, DIRTY_CLIENTS_ALL); - qemu_ram_setup_dump(new_block->host, new_block->length); - //qemu_madvise(new_block->host, new_block->length, QEMU_MADV_HUGEPAGE); - //qemu_madvise(new_block->host, new_block->length, QEMU_MADV_DONTFORK); + qemu_ram_setup_dump(new_block->host, new_block->max_length); + //qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_HUGEPAGE); + //qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_DONTFORK); return new_block->offset; } // return -1 on error -ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, - MemoryRegion *mr, Error **errp) +static +ram_addr_t qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size, + void (*resized)(const char*, + uint64_t length, + void *host), + void *host, bool resizeable, + MemoryRegion *mr, Error **errp) { RAMBlock *new_block; ram_addr_t addr; Error *local_err = NULL; size = TARGET_PAGE_ALIGN(size); + max_size = TARGET_PAGE_ALIGN(max_size); new_block = g_malloc0(sizeof(*new_block)); - if (new_block == NULL) + if (new_block == NULL) { return -1; - + } new_block->mr = mr; - new_block->length = size; + new_block->resized = resized; + new_block->used_length = size; + new_block->max_length = max_size; + assert(max_size >= size); new_block->fd = -1; new_block->host = host; if (host) { new_block->flags |= RAM_PREALLOC; } + if (resizeable) { + new_block->flags |= RAM_RESIZEABLE; + } addr = ram_block_add(mr->uc, new_block, &local_err); if (local_err) { g_free(new_block); @@ -1081,9 +1142,24 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, return addr; } +ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, + MemoryRegion *mr, Error **errp) +{ + return qemu_ram_alloc_internal(size, size, NULL, host, false, mr, errp); +} + ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr, Error **errp) { - return qemu_ram_alloc_from_ptr(size, NULL, mr, errp); + return qemu_ram_alloc_internal(size, size, NULL, NULL, false, mr, errp); +} + +ram_addr_t qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t maxsz, + void (*resized)(const char*, + uint64_t length, + void *host), + MemoryRegion *mr, Error **errp) +{ + return qemu_ram_alloc_internal(size, maxsz, resized, NULL, true, mr, errp); } void qemu_ram_free_from_ptr(struct uc_struct *uc, ram_addr_t addr) @@ -1114,11 +1190,11 @@ void qemu_ram_free(struct uc_struct *uc, ram_addr_t addr) ; #ifndef _WIN32 } else if (block->fd >= 0) { - munmap(block->host, block->length); + munmap(block->host, block->max_length); close(block->fd); #endif } else { - qemu_anon_ram_free(block->host, block->length); + qemu_anon_ram_free(block->host, block->max_length); } g_free(block); break; @@ -1136,8 +1212,8 @@ void qemu_ram_remap(struct uc_struct *uc, ram_addr_t addr, ram_addr_t length) QTAILQ_FOREACH(block, &uc->ram_list.blocks, next) { offset = addr - block->offset; - if (offset < block->length) { - vaddr = block->host + offset; + if (offset < block->max_length) { + vaddr = ramblock_ptr(block, offset); if (block->flags & RAM_PREALLOC) { ; } else { @@ -1214,10 +1290,10 @@ static void *qemu_ram_ptr_length(struct uc_struct *uc, ram_addr_t addr, hwaddr * } QTAILQ_FOREACH(block, &uc->ram_list.blocks, next) { - if (addr - block->offset < block->length) { - if (addr - block->offset + *size > block->length) - *size = block->length - addr + block->offset; - return block->host + (addr - block->offset); + if (addr - block->offset < block->max_length) { + if (addr - block->offset + *size > block->max_length) + *size = block->max_length - addr + block->offset; + return ramblock_ptr(block, addr - block->offset); } } @@ -1233,7 +1309,7 @@ MemoryRegion *qemu_ram_addr_from_host(struct uc_struct *uc, void *ptr, ram_addr_ uint8_t *host = ptr; block = uc->ram_list.mru_block; - if (block && block->host && host - block->host < block->length) { + if (block && block->host && host - block->host < block->max_length) { goto found; } @@ -1242,7 +1318,7 @@ MemoryRegion *qemu_ram_addr_from_host(struct uc_struct *uc, void *ptr, ram_addr_ if (block->host == NULL) { continue; } - if (host - block->host < block->length) { + if (host - block->host < block->max_length) { goto found; } } @@ -2596,7 +2672,7 @@ void qemu_ram_foreach_block(struct uc_struct *uc, RAMBlockIterFunc func, void *o RAMBlock *block; QTAILQ_FOREACH(block, &uc->ram_list.blocks, next) { - func(block->host, block->offset, block->length, opaque); + func(block->host, block->offset, block->used_length, opaque); } } #endif diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 8e917619..f1179ebc 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -2091,6 +2091,7 @@ symbols = ( 'memory_region_init_ram', 'memory_region_init_ram_ptr', 'memory_region_init_reservation', + 'memory_region_init_resizeable_ram', 'memory_region_is_iommu', 'memory_region_is_logging', 'memory_region_is_mapped', @@ -2440,11 +2441,13 @@ symbols = ( 'qemu_ram_addr_from_host_nofail', 'qemu_ram_alloc', 'qemu_ram_alloc_from_ptr', + 'qemu_ram_alloc_resizeable', 'qemu_ram_foreach_block', 'qemu_ram_free', 'qemu_ram_free_from_ptr', 'qemu_ram_ptr_length', 'qemu_ram_remap', + 'qemu_ram_resize', 'qemu_ram_setup_dump', 'qemu_ram_unset_idstr', 'qemu_real_host_page_size', diff --git a/qemu/include/exec/memory.h b/qemu/include/exec/memory.h index 73dfabe1..a4627f29 100644 --- a/qemu/include/exec/memory.h +++ b/qemu/include/exec/memory.h @@ -395,6 +395,32 @@ void memory_region_init_rom_device(MemoryRegion *mr, uint64_t size, Error **errp); +/** + * memory_region_init_resizeable_ram: Initialize memory region with resizeable + * RAM. Accesses into the region will + * modify memory directly. Only an initial + * portion of this RAM is actually used. + * The used size can change across reboots. + * + * @mr: the #MemoryRegion to be initialized. + * @owner: the object that tracks the region's reference count + * @name: the name of the region. + * @size: used size of the region. + * @max_size: max size of the region. + * @resized: callback to notify owner about used size change. + * @errp: pointer to Error*, to store an error if it happens. + */ +void memory_region_init_resizeable_ram(struct uc_struct *uc, + MemoryRegion *mr, + struct Object *owner, + const char *name, + uint64_t size, + uint64_t max_size, + void (*resized)(const char*, + uint64_t length, + void *host), + Error **errp); + /** * memory_region_init_reservation: Initialize a memory region that reserves * I/O space. diff --git a/qemu/include/exec/ram_addr.h b/qemu/include/exec/ram_addr.h index 5453aa35..34791d70 100644 --- a/qemu/include/exec/ram_addr.h +++ b/qemu/include/exec/ram_addr.h @@ -26,12 +26,19 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, MemoryRegion *mr, Error **errp); ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr, Error **errp); +ram_addr_t qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t max_size, + void (*resized)(const char*, + uint64_t length, + void *host), + MemoryRegion *mr, Error **errp); int qemu_get_ram_fd(struct uc_struct *uc, ram_addr_t addr); void *qemu_get_ram_block_host_ptr(struct uc_struct *uc, ram_addr_t addr); void *qemu_get_ram_ptr(struct uc_struct *uc, ram_addr_t addr); void qemu_ram_free(struct uc_struct *c, ram_addr_t addr); void qemu_ram_free_from_ptr(struct uc_struct *uc, ram_addr_t addr); +int qemu_ram_resize(struct uc_struct *c, ram_addr_t base, ram_addr_t newsize, Error **errp); + #define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1) #define DIRTY_CLIENTS_NOCODE (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE)) @@ -169,8 +176,7 @@ bool cpu_physical_memory_test_and_clear_dirty(struct uc_struct *uc, unsigned client); static inline void cpu_physical_memory_clear_dirty_range(struct uc_struct *uc, ram_addr_t start, - ram_addr_t length, - unsigned client) + ram_addr_t length) { cpu_physical_memory_test_and_clear_dirty(uc, start, length, DIRTY_MEMORY_CODE); } diff --git a/qemu/m68k.h b/qemu/m68k.h index 47ab4d52..54f14515 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -2085,6 +2085,7 @@ #define memory_region_init_ram memory_region_init_ram_m68k #define memory_region_init_ram_ptr memory_region_init_ram_ptr_m68k #define memory_region_init_reservation memory_region_init_reservation_m68k +#define memory_region_init_resizeable_ram memory_region_init_resizeable_ram_m68k #define memory_region_is_iommu memory_region_is_iommu_m68k #define memory_region_is_logging memory_region_is_logging_m68k #define memory_region_is_mapped memory_region_is_mapped_m68k @@ -2434,11 +2435,13 @@ #define qemu_ram_addr_from_host_nofail qemu_ram_addr_from_host_nofail_m68k #define qemu_ram_alloc qemu_ram_alloc_m68k #define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_m68k +#define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_m68k #define qemu_ram_foreach_block qemu_ram_foreach_block_m68k #define qemu_ram_free qemu_ram_free_m68k #define qemu_ram_free_from_ptr qemu_ram_free_from_ptr_m68k #define qemu_ram_ptr_length qemu_ram_ptr_length_m68k #define qemu_ram_remap qemu_ram_remap_m68k +#define qemu_ram_resize qemu_ram_resize_m68k #define qemu_ram_setup_dump qemu_ram_setup_dump_m68k #define qemu_ram_unset_idstr qemu_ram_unset_idstr_m68k #define qemu_real_host_page_size qemu_real_host_page_size_m68k diff --git a/qemu/memory.c b/qemu/memory.c index 7fe2db50..6a614798 100644 --- a/qemu/memory.c +++ b/qemu/memory.c @@ -1186,6 +1186,25 @@ void memory_region_init_ram_ptr(struct uc_struct *uc, MemoryRegion *mr, mr->ram_addr = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_abort); } +void memory_region_init_resizeable_ram(struct uc_struct *uc, + MemoryRegion *mr, + Object *owner, + const char *name, + uint64_t size, + uint64_t max_size, + void (*resized)(const char*, + uint64_t length, + void *host), + Error **errp) +{ + memory_region_init(uc, mr, owner, name, size); + mr->ram = true; + mr->terminates = true; + mr->destructor = memory_region_destructor_ram; + mr->ram_addr = qemu_ram_alloc_resizeable(size, max_size, resized, mr, errp); + mr->dirty_log_mask = tcg_enabled(uc) ? (1 << DIRTY_MEMORY_CODE) : 0; +} + void memory_region_set_skip_dump(MemoryRegion *mr) { mr->skip_dump = true; diff --git a/qemu/mips.h b/qemu/mips.h index 63570e07..aada73d9 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -2085,6 +2085,7 @@ #define memory_region_init_ram memory_region_init_ram_mips #define memory_region_init_ram_ptr memory_region_init_ram_ptr_mips #define memory_region_init_reservation memory_region_init_reservation_mips +#define memory_region_init_resizeable_ram memory_region_init_resizeable_ram_mips #define memory_region_is_iommu memory_region_is_iommu_mips #define memory_region_is_logging memory_region_is_logging_mips #define memory_region_is_mapped memory_region_is_mapped_mips @@ -2434,11 +2435,13 @@ #define qemu_ram_addr_from_host_nofail qemu_ram_addr_from_host_nofail_mips #define qemu_ram_alloc qemu_ram_alloc_mips #define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_mips +#define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_mips #define qemu_ram_foreach_block qemu_ram_foreach_block_mips #define qemu_ram_free qemu_ram_free_mips #define qemu_ram_free_from_ptr qemu_ram_free_from_ptr_mips #define qemu_ram_ptr_length qemu_ram_ptr_length_mips #define qemu_ram_remap qemu_ram_remap_mips +#define qemu_ram_resize qemu_ram_resize_mips #define qemu_ram_setup_dump qemu_ram_setup_dump_mips #define qemu_ram_unset_idstr qemu_ram_unset_idstr_mips #define qemu_real_host_page_size qemu_real_host_page_size_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index f0ee34c1..cad2cd26 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -2085,6 +2085,7 @@ #define memory_region_init_ram memory_region_init_ram_mips64 #define memory_region_init_ram_ptr memory_region_init_ram_ptr_mips64 #define memory_region_init_reservation memory_region_init_reservation_mips64 +#define memory_region_init_resizeable_ram memory_region_init_resizeable_ram_mips64 #define memory_region_is_iommu memory_region_is_iommu_mips64 #define memory_region_is_logging memory_region_is_logging_mips64 #define memory_region_is_mapped memory_region_is_mapped_mips64 @@ -2434,11 +2435,13 @@ #define qemu_ram_addr_from_host_nofail qemu_ram_addr_from_host_nofail_mips64 #define qemu_ram_alloc qemu_ram_alloc_mips64 #define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_mips64 +#define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_mips64 #define qemu_ram_foreach_block qemu_ram_foreach_block_mips64 #define qemu_ram_free qemu_ram_free_mips64 #define qemu_ram_free_from_ptr qemu_ram_free_from_ptr_mips64 #define qemu_ram_ptr_length qemu_ram_ptr_length_mips64 #define qemu_ram_remap qemu_ram_remap_mips64 +#define qemu_ram_resize qemu_ram_resize_mips64 #define qemu_ram_setup_dump qemu_ram_setup_dump_mips64 #define qemu_ram_unset_idstr qemu_ram_unset_idstr_mips64 #define qemu_real_host_page_size qemu_real_host_page_size_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index c0db6e31..bda5fe07 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -2085,6 +2085,7 @@ #define memory_region_init_ram memory_region_init_ram_mips64el #define memory_region_init_ram_ptr memory_region_init_ram_ptr_mips64el #define memory_region_init_reservation memory_region_init_reservation_mips64el +#define memory_region_init_resizeable_ram memory_region_init_resizeable_ram_mips64el #define memory_region_is_iommu memory_region_is_iommu_mips64el #define memory_region_is_logging memory_region_is_logging_mips64el #define memory_region_is_mapped memory_region_is_mapped_mips64el @@ -2434,11 +2435,13 @@ #define qemu_ram_addr_from_host_nofail qemu_ram_addr_from_host_nofail_mips64el #define qemu_ram_alloc qemu_ram_alloc_mips64el #define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_mips64el +#define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_mips64el #define qemu_ram_foreach_block qemu_ram_foreach_block_mips64el #define qemu_ram_free qemu_ram_free_mips64el #define qemu_ram_free_from_ptr qemu_ram_free_from_ptr_mips64el #define qemu_ram_ptr_length qemu_ram_ptr_length_mips64el #define qemu_ram_remap qemu_ram_remap_mips64el +#define qemu_ram_resize qemu_ram_resize_mips64el #define qemu_ram_setup_dump qemu_ram_setup_dump_mips64el #define qemu_ram_unset_idstr qemu_ram_unset_idstr_mips64el #define qemu_real_host_page_size qemu_real_host_page_size_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index ea39989f..9dc605c3 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -2085,6 +2085,7 @@ #define memory_region_init_ram memory_region_init_ram_mipsel #define memory_region_init_ram_ptr memory_region_init_ram_ptr_mipsel #define memory_region_init_reservation memory_region_init_reservation_mipsel +#define memory_region_init_resizeable_ram memory_region_init_resizeable_ram_mipsel #define memory_region_is_iommu memory_region_is_iommu_mipsel #define memory_region_is_logging memory_region_is_logging_mipsel #define memory_region_is_mapped memory_region_is_mapped_mipsel @@ -2434,11 +2435,13 @@ #define qemu_ram_addr_from_host_nofail qemu_ram_addr_from_host_nofail_mipsel #define qemu_ram_alloc qemu_ram_alloc_mipsel #define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_mipsel +#define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_mipsel #define qemu_ram_foreach_block qemu_ram_foreach_block_mipsel #define qemu_ram_free qemu_ram_free_mipsel #define qemu_ram_free_from_ptr qemu_ram_free_from_ptr_mipsel #define qemu_ram_ptr_length qemu_ram_ptr_length_mipsel #define qemu_ram_remap qemu_ram_remap_mipsel +#define qemu_ram_resize qemu_ram_resize_mipsel #define qemu_ram_setup_dump qemu_ram_setup_dump_mipsel #define qemu_ram_unset_idstr qemu_ram_unset_idstr_mipsel #define qemu_real_host_page_size qemu_real_host_page_size_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index ea2c1054..33ad67b6 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -2085,6 +2085,7 @@ #define memory_region_init_ram memory_region_init_ram_powerpc #define memory_region_init_ram_ptr memory_region_init_ram_ptr_powerpc #define memory_region_init_reservation memory_region_init_reservation_powerpc +#define memory_region_init_resizeable_ram memory_region_init_resizeable_ram_powerpc #define memory_region_is_iommu memory_region_is_iommu_powerpc #define memory_region_is_logging memory_region_is_logging_powerpc #define memory_region_is_mapped memory_region_is_mapped_powerpc @@ -2434,11 +2435,13 @@ #define qemu_ram_addr_from_host_nofail qemu_ram_addr_from_host_nofail_powerpc #define qemu_ram_alloc qemu_ram_alloc_powerpc #define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_powerpc +#define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_powerpc #define qemu_ram_foreach_block qemu_ram_foreach_block_powerpc #define qemu_ram_free qemu_ram_free_powerpc #define qemu_ram_free_from_ptr qemu_ram_free_from_ptr_powerpc #define qemu_ram_ptr_length qemu_ram_ptr_length_powerpc #define qemu_ram_remap qemu_ram_remap_powerpc +#define qemu_ram_resize qemu_ram_resize_powerpc #define qemu_ram_setup_dump qemu_ram_setup_dump_powerpc #define qemu_ram_unset_idstr qemu_ram_unset_idstr_powerpc #define qemu_real_host_page_size qemu_real_host_page_size_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index 7774c8a1..4f7437b2 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -2085,6 +2085,7 @@ #define memory_region_init_ram memory_region_init_ram_sparc #define memory_region_init_ram_ptr memory_region_init_ram_ptr_sparc #define memory_region_init_reservation memory_region_init_reservation_sparc +#define memory_region_init_resizeable_ram memory_region_init_resizeable_ram_sparc #define memory_region_is_iommu memory_region_is_iommu_sparc #define memory_region_is_logging memory_region_is_logging_sparc #define memory_region_is_mapped memory_region_is_mapped_sparc @@ -2434,11 +2435,13 @@ #define qemu_ram_addr_from_host_nofail qemu_ram_addr_from_host_nofail_sparc #define qemu_ram_alloc qemu_ram_alloc_sparc #define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_sparc +#define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_sparc #define qemu_ram_foreach_block qemu_ram_foreach_block_sparc #define qemu_ram_free qemu_ram_free_sparc #define qemu_ram_free_from_ptr qemu_ram_free_from_ptr_sparc #define qemu_ram_ptr_length qemu_ram_ptr_length_sparc #define qemu_ram_remap qemu_ram_remap_sparc +#define qemu_ram_resize qemu_ram_resize_sparc #define qemu_ram_setup_dump qemu_ram_setup_dump_sparc #define qemu_ram_unset_idstr qemu_ram_unset_idstr_sparc #define qemu_real_host_page_size qemu_real_host_page_size_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 2ddfde3f..4347750e 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -2085,6 +2085,7 @@ #define memory_region_init_ram memory_region_init_ram_sparc64 #define memory_region_init_ram_ptr memory_region_init_ram_ptr_sparc64 #define memory_region_init_reservation memory_region_init_reservation_sparc64 +#define memory_region_init_resizeable_ram memory_region_init_resizeable_ram_sparc64 #define memory_region_is_iommu memory_region_is_iommu_sparc64 #define memory_region_is_logging memory_region_is_logging_sparc64 #define memory_region_is_mapped memory_region_is_mapped_sparc64 @@ -2434,11 +2435,13 @@ #define qemu_ram_addr_from_host_nofail qemu_ram_addr_from_host_nofail_sparc64 #define qemu_ram_alloc qemu_ram_alloc_sparc64 #define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_sparc64 +#define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_sparc64 #define qemu_ram_foreach_block qemu_ram_foreach_block_sparc64 #define qemu_ram_free qemu_ram_free_sparc64 #define qemu_ram_free_from_ptr qemu_ram_free_from_ptr_sparc64 #define qemu_ram_ptr_length qemu_ram_ptr_length_sparc64 #define qemu_ram_remap qemu_ram_remap_sparc64 +#define qemu_ram_resize qemu_ram_resize_sparc64 #define qemu_ram_setup_dump qemu_ram_setup_dump_sparc64 #define qemu_ram_unset_idstr qemu_ram_unset_idstr_sparc64 #define qemu_real_host_page_size qemu_real_host_page_size_sparc64 diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 41723893..6766b97f 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -2085,6 +2085,7 @@ #define memory_region_init_ram memory_region_init_ram_x86_64 #define memory_region_init_ram_ptr memory_region_init_ram_ptr_x86_64 #define memory_region_init_reservation memory_region_init_reservation_x86_64 +#define memory_region_init_resizeable_ram memory_region_init_resizeable_ram_x86_64 #define memory_region_is_iommu memory_region_is_iommu_x86_64 #define memory_region_is_logging memory_region_is_logging_x86_64 #define memory_region_is_mapped memory_region_is_mapped_x86_64 @@ -2434,11 +2435,13 @@ #define qemu_ram_addr_from_host_nofail qemu_ram_addr_from_host_nofail_x86_64 #define qemu_ram_alloc qemu_ram_alloc_x86_64 #define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_x86_64 +#define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_x86_64 #define qemu_ram_foreach_block qemu_ram_foreach_block_x86_64 #define qemu_ram_free qemu_ram_free_x86_64 #define qemu_ram_free_from_ptr qemu_ram_free_from_ptr_x86_64 #define qemu_ram_ptr_length qemu_ram_ptr_length_x86_64 #define qemu_ram_remap qemu_ram_remap_x86_64 +#define qemu_ram_resize qemu_ram_resize_x86_64 #define qemu_ram_setup_dump qemu_ram_setup_dump_x86_64 #define qemu_ram_unset_idstr qemu_ram_unset_idstr_x86_64 #define qemu_real_host_page_size qemu_real_host_page_size_x86_64