diff --git a/qemu/exec.c b/qemu/exec.c index 987bfdfb..5e2e4102 100644 --- a/qemu/exec.c +++ b/qemu/exec.c @@ -1087,7 +1087,7 @@ int qemu_ram_resize(struct uc_struct *uc, ram_addr_t base, ram_addr_t newsize, E return 0; } -static ram_addr_t ram_block_add(struct uc_struct *uc, RAMBlock *new_block, Error **errp) +static void ram_block_add(struct uc_struct *uc, RAMBlock *new_block, Error **errp) { RAMBlock *block; RAMBlock *last_block = NULL; @@ -1104,7 +1104,6 @@ static ram_addr_t ram_block_add(struct uc_struct *uc, RAMBlock *new_block, Error error_setg_errno(errp, errno, "cannot set up guest memory '%s'", memory_region_name(new_block->mr)); - return -1; } memory_try_enable_merging(new_block->host, new_block->max_length); } @@ -1155,13 +1154,10 @@ static ram_addr_t ram_block_add(struct uc_struct *uc, RAMBlock *new_block, Error // kvm_setup_guest_memory(new_block->host, new_block->max_length); //} } - - return new_block->offset; } -// return -1 on error static -ram_addr_t qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size, +RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size, void (*resized)(const char*, uint64_t length, void *host), @@ -1169,14 +1165,13 @@ ram_addr_t qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size, 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) { - return -1; + return NULL; } new_block->mr = mr; new_block->resized = resized; @@ -1191,32 +1186,32 @@ ram_addr_t qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size, if (resizeable) { new_block->flags |= RAM_RESIZEABLE; } - addr = ram_block_add(mr->uc, new_block, &local_err); + ram_block_add(mr->uc, new_block, &local_err); if (local_err) { g_free(new_block); error_propagate(errp, local_err); - return -1; + return NULL; } mr->ram_block = new_block; - return addr; + return new_block; } -ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, - MemoryRegion *mr, Error **errp) +RAMBlock *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) +RAMBlock *qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr, Error **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) +RAMBlock *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); } diff --git a/qemu/include/exec/ram_addr.h b/qemu/include/exec/ram_addr.h index 4a00cde4..c0dca1b5 100644 --- a/qemu/include/exec/ram_addr.h +++ b/qemu/include/exec/ram_addr.h @@ -53,14 +53,14 @@ static inline void *ramblock_ptr(RAMBlock *block, ram_addr_t offset) return (char *)block->host + offset; } -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); +RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, + MemoryRegion *mr, Error **errp); +RAMBlock *qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr, Error **errp); +RAMBlock *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_ram_free(struct uc_struct *c, ram_addr_t addr); diff --git a/qemu/memory.c b/qemu/memory.c index 2b6aa2b1..91fcd039 100644 --- a/qemu/memory.c +++ b/qemu/memory.c @@ -1163,6 +1163,8 @@ void memory_region_init_ram(struct uc_struct *uc, MemoryRegion *mr, uint32_t perms, Error **errp) { + RAMBlock *ram_block; + memory_region_init(uc, mr, owner, name, size); mr->ram = true; if (!(perms & UC_PROT_WRITE)) { @@ -1171,7 +1173,8 @@ void memory_region_init_ram(struct uc_struct *uc, MemoryRegion *mr, mr->perms = perms; mr->terminates = true; mr->destructor = memory_region_destructor_ram; - mr->ram_addr = qemu_ram_alloc(size, mr, errp); + ram_block = qemu_ram_alloc(size, mr, errp); + mr->ram_addr = ram_block->offset; mr->dirty_log_mask = tcg_enabled(uc) ? (1 << DIRTY_MEMORY_CODE) : 0; } @@ -1181,6 +1184,7 @@ void memory_region_init_ram_ptr(struct uc_struct *uc, MemoryRegion *mr, uint64_t size, void *ptr) { + RAMBlock *ram_block; memory_region_init(uc, mr, owner, name, size); mr->ram = true; mr->terminates = true; @@ -1189,7 +1193,8 @@ void memory_region_init_ram_ptr(struct uc_struct *uc, MemoryRegion *mr, /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL. */ assert(ptr != NULL); - mr->ram_addr = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_abort); + ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_abort); + mr->ram_addr = ram_block->offset; } void memory_region_init_resizeable_ram(struct uc_struct *uc, @@ -1203,11 +1208,14 @@ void memory_region_init_resizeable_ram(struct uc_struct *uc, void *host), Error **errp) { + RAMBlock *ram_block; + 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); + ram_block = qemu_ram_alloc_resizeable(size, max_size, resized, mr, errp); + mr->ram_addr = ram_block->offset; mr->dirty_log_mask = tcg_enabled(uc) ? (1 << DIRTY_MEMORY_CODE) : 0; } @@ -1367,13 +1375,22 @@ int memory_region_get_fd(MemoryRegion *mr) void *memory_region_get_ram_ptr(MemoryRegion *mr) { - if (mr->alias) { - return (char*)memory_region_get_ram_ptr(mr->alias) + mr->alias_offset; + void *ptr; + uint64_t offset = 0; + + // Unicorn: commented out + // rcu_read_lock(); + while (mr->alias) { + offset += mr->alias_offset; + mr = mr->alias; } - assert(mr->terminates); + assert(mr->ram_addr != RAM_ADDR_INVALID); + ptr = qemu_get_ram_ptr(mr->uc, mr->ram_block, mr->ram_addr & TARGET_PAGE_MASK); + // Unicorn: commented out + //rcu_read_unlock(); - return qemu_get_ram_ptr(mr->uc, mr->ram_block, mr->ram_addr & TARGET_PAGE_MASK); + return ptr + offset; } bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr,