diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 2da3fcd0..63e694b8 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -2079,6 +2079,7 @@ #define memory_region_escape_name memory_region_escape_name_aarch64 #define memory_region_finalize memory_region_finalize_aarch64 #define memory_region_find memory_region_find_aarch64 +#define memory_region_from_host memory_region_from_host_aarch64 #define memory_region_get_addr memory_region_get_addr_aarch64 #define memory_region_get_alignment memory_region_get_alignment_aarch64 #define memory_region_get_container memory_region_get_container_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 6bf0f43f..511791bc 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -2079,6 +2079,7 @@ #define memory_region_escape_name memory_region_escape_name_aarch64eb #define memory_region_finalize memory_region_finalize_aarch64eb #define memory_region_find memory_region_find_aarch64eb +#define memory_region_from_host memory_region_from_host_aarch64eb #define memory_region_get_addr memory_region_get_addr_aarch64eb #define memory_region_get_alignment memory_region_get_alignment_aarch64eb #define memory_region_get_container memory_region_get_container_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index d4732f4a..6f2948e1 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -2079,6 +2079,7 @@ #define memory_region_escape_name memory_region_escape_name_arm #define memory_region_finalize memory_region_finalize_arm #define memory_region_find memory_region_find_arm +#define memory_region_from_host memory_region_from_host_arm #define memory_region_get_addr memory_region_get_addr_arm #define memory_region_get_alignment memory_region_get_alignment_arm #define memory_region_get_container memory_region_get_container_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index a741c0b1..d80b41e8 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -2079,6 +2079,7 @@ #define memory_region_escape_name memory_region_escape_name_armeb #define memory_region_finalize memory_region_finalize_armeb #define memory_region_find memory_region_find_armeb +#define memory_region_from_host memory_region_from_host_armeb #define memory_region_get_addr memory_region_get_addr_armeb #define memory_region_get_alignment memory_region_get_alignment_armeb #define memory_region_get_container memory_region_get_container_armeb diff --git a/qemu/cputlb.c b/qemu/cputlb.c index 2cdd402c..0bacab6a 100644 --- a/qemu/cputlb.c +++ b/qemu/cputlb.c @@ -62,7 +62,7 @@ static void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr); static bool tlb_is_dirty_ram(CPUTLBEntry *tlbe); -static bool qemu_ram_addr_from_host_nofail(struct uc_struct *uc, void *ptr, ram_addr_t *addr); +static ram_addr_t qemu_ram_addr_from_host_nofail(struct uc_struct *uc, void *ptr); static void tlb_add_large_page(CPUArchState *env, target_ulong vaddr, target_ulong size); static void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr); @@ -307,7 +307,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr) cpu_ldub_code(env1, addr); //check for NX related error from softmmu if (env1->invalid_error == UC_ERR_FETCH_PROT) { - return -1; + return RAM_ADDR_INVALID; } } iotlbentry = &env1->iotlb[mmu_idx][page_index]; @@ -323,26 +323,31 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr) // TARGET_FMT_lx "\n", addr); // qq env1->invalid_addr = addr; env1->invalid_error = UC_ERR_FETCH_UNMAPPED; - return -1; + return RAM_ADDR_INVALID; } } p = (void *)((uintptr_t)addr + env1->tlb_table[mmu_idx][page_index].addend); - if (!qemu_ram_addr_from_host_nofail(cpu->uc, p, &ram_addr)) { + ram_addr = qemu_ram_addr_from_host_nofail(cpu->uc, p); + if (ram_addr == RAM_ADDR_INVALID) { env1->invalid_addr = addr; env1->invalid_error = UC_ERR_FETCH_UNMAPPED; - return -1; - } else + return RAM_ADDR_INVALID; + } else { return ram_addr; + } } -static bool qemu_ram_addr_from_host_nofail(struct uc_struct *uc, void *ptr, ram_addr_t *ram_addr) +static ram_addr_t qemu_ram_addr_from_host_nofail(struct uc_struct *uc, void *ptr) { - if (qemu_ram_addr_from_host(uc, ptr, ram_addr) == NULL) { + ram_addr_t ram_addr; + + ram_addr = qemu_ram_addr_from_host(uc, ptr); + if (ram_addr == RAM_ADDR_INVALID) { // fprintf(stderr, "Bad ram pointer %p\n", ptr); - return false; + return RAM_ADDR_INVALID; } - return true; + return ram_addr; } static void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr) diff --git a/qemu/exec.c b/qemu/exec.c index 0ec5706c..8214c5c4 100644 --- a/qemu/exec.c +++ b/qemu/exec.c @@ -1486,18 +1486,17 @@ RAMBlock *qemu_ram_block_by_name(struct uc_struct* uc, const char *name) /* Some of the softmmu routines need to translate from a host pointer (typically a TLB entry) back to a ram offset. */ -MemoryRegion *qemu_ram_addr_from_host(struct uc_struct* uc, void *ptr, ram_addr_t *ram_addr) +ram_addr_t qemu_ram_addr_from_host(struct uc_struct* uc, void *ptr) { RAMBlock *block; ram_addr_t offset; block = qemu_ram_block_from_host(uc, ptr, false, &offset); - *ram_addr = block->offset + offset; if (!block) { - return NULL; + return RAM_ADDR_INVALID; } - return block->mr; + return block->offset + offset; } static MemTxResult subpage_read(struct uc_struct* uc, void *opaque, hwaddr addr, @@ -2301,8 +2300,9 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, MemoryRegion *mr; ram_addr_t addr1; - mr = qemu_ram_addr_from_host(as->uc, buffer, &addr1); + mr = memory_region_from_host(as->uc, buffer, &addr1); assert(mr != NULL); + addr1 += memory_region_get_ram_addr(mr); if (is_write) { invalidate_and_set_dirty(mr, addr1, access_len); } diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 804588c4..468622c9 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -2085,6 +2085,7 @@ symbols = ( 'memory_region_escape_name', 'memory_region_finalize', 'memory_region_find', + 'memory_region_from_host', 'memory_region_get_addr', 'memory_region_get_alignment', 'memory_region_get_container', diff --git a/qemu/include/exec/cpu-common.h b/qemu/include/exec/cpu-common.h index 20a272e9..449aebe1 100644 --- a/qemu/include/exec/cpu-common.h +++ b/qemu/include/exec/cpu-common.h @@ -48,7 +48,7 @@ typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr); void qemu_ram_remap(struct uc_struct *uc, ram_addr_t addr, ram_addr_t length); /* This should not be used by devices. */ -MemoryRegion *qemu_ram_addr_from_host(struct uc_struct* uc, void *ptr, ram_addr_t *ram_addr); +ram_addr_t qemu_ram_addr_from_host(struct uc_struct* uc, void *ptr); RAMBlock *qemu_ram_block_by_name(struct uc_struct* uc, const char *name); RAMBlock *qemu_ram_block_from_host(struct uc_struct* uc, void *ptr, bool round_offset, ram_addr_t *offset); diff --git a/qemu/include/exec/memory.h b/qemu/include/exec/memory.h index d96548e1..d579f906 100644 --- a/qemu/include/exec/memory.h +++ b/qemu/include/exec/memory.h @@ -26,6 +26,7 @@ #include "qom/object.h" #include "qemu/typedefs.h" +#define RAM_ADDR_INVALID (~(ram_addr_t)0) #define MAX_PHYS_ADDR_SPACE_BITS 62 #define MAX_PHYS_ADDR (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1) @@ -596,6 +597,24 @@ static inline bool memory_region_is_rom(MemoryRegion *mr) */ int memory_region_get_fd(MemoryRegion *mr); +/** + * memory_region_from_host: Convert a pointer into a RAM memory region + * and an offset within it. + * + * Given a host pointer inside a RAM memory region (created with + * memory_region_init_ram() or memory_region_init_ram_ptr()), return + * the MemoryRegion and the offset within it. + * + * Use with care; by the time this function returns, the returned pointer is + * not protected by RCU anymore. If the caller is not within an RCU critical + * section and does not hold the iothread lock, it must have other means of + * protecting the pointer, such as a reference to the region that includes + * the incoming ram_addr_t. + * + * @mr: the memory region being queried. + */ +MemoryRegion *memory_region_from_host(struct uc_struct *uc, void *ptr, ram_addr_t *offset); + /** * memory_region_get_ram_ptr: Get a pointer into a RAM memory region. * diff --git a/qemu/m68k.h b/qemu/m68k.h index ab9a9a71..f32b39af 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -2079,6 +2079,7 @@ #define memory_region_escape_name memory_region_escape_name_m68k #define memory_region_finalize memory_region_finalize_m68k #define memory_region_find memory_region_find_m68k +#define memory_region_from_host memory_region_from_host_m68k #define memory_region_get_addr memory_region_get_addr_m68k #define memory_region_get_alignment memory_region_get_alignment_m68k #define memory_region_get_container memory_region_get_container_m68k diff --git a/qemu/memory.c b/qemu/memory.c index bec0148d..0d5b704f 100644 --- a/qemu/memory.c +++ b/qemu/memory.c @@ -1364,6 +1364,18 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr) return ptr + offset; } +MemoryRegion *memory_region_from_host(struct uc_struct *uc, void *ptr, ram_addr_t *offset) +{ + RAMBlock *block; + + block = qemu_ram_block_from_host(uc, ptr, false, offset); + if (!block) { + return NULL; + } + + return block->mr; +} + ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr) { return mr->ram_block ? mr->ram_block->offset : RAM_ADDR_INVALID; diff --git a/qemu/mips.h b/qemu/mips.h index 8d0c87d5..3caf804f 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -2079,6 +2079,7 @@ #define memory_region_escape_name memory_region_escape_name_mips #define memory_region_finalize memory_region_finalize_mips #define memory_region_find memory_region_find_mips +#define memory_region_from_host memory_region_from_host_mips #define memory_region_get_addr memory_region_get_addr_mips #define memory_region_get_alignment memory_region_get_alignment_mips #define memory_region_get_container memory_region_get_container_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 2a3d1c6e..500cca3e 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -2079,6 +2079,7 @@ #define memory_region_escape_name memory_region_escape_name_mips64 #define memory_region_finalize memory_region_finalize_mips64 #define memory_region_find memory_region_find_mips64 +#define memory_region_from_host memory_region_from_host_mips64 #define memory_region_get_addr memory_region_get_addr_mips64 #define memory_region_get_alignment memory_region_get_alignment_mips64 #define memory_region_get_container memory_region_get_container_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 7aa1e48e..a5d8a2d4 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -2079,6 +2079,7 @@ #define memory_region_escape_name memory_region_escape_name_mips64el #define memory_region_finalize memory_region_finalize_mips64el #define memory_region_find memory_region_find_mips64el +#define memory_region_from_host memory_region_from_host_mips64el #define memory_region_get_addr memory_region_get_addr_mips64el #define memory_region_get_alignment memory_region_get_alignment_mips64el #define memory_region_get_container memory_region_get_container_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index e7abd5a8..5bfa4ba2 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -2079,6 +2079,7 @@ #define memory_region_escape_name memory_region_escape_name_mipsel #define memory_region_finalize memory_region_finalize_mipsel #define memory_region_find memory_region_find_mipsel +#define memory_region_from_host memory_region_from_host_mipsel #define memory_region_get_addr memory_region_get_addr_mipsel #define memory_region_get_alignment memory_region_get_alignment_mipsel #define memory_region_get_container memory_region_get_container_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 2362d06b..c17ed3c7 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -2079,6 +2079,7 @@ #define memory_region_escape_name memory_region_escape_name_powerpc #define memory_region_finalize memory_region_finalize_powerpc #define memory_region_find memory_region_find_powerpc +#define memory_region_from_host memory_region_from_host_powerpc #define memory_region_get_addr memory_region_get_addr_powerpc #define memory_region_get_alignment memory_region_get_alignment_powerpc #define memory_region_get_container memory_region_get_container_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index 3d324c9c..2331f7b6 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -2079,6 +2079,7 @@ #define memory_region_escape_name memory_region_escape_name_sparc #define memory_region_finalize memory_region_finalize_sparc #define memory_region_find memory_region_find_sparc +#define memory_region_from_host memory_region_from_host_sparc #define memory_region_get_addr memory_region_get_addr_sparc #define memory_region_get_alignment memory_region_get_alignment_sparc #define memory_region_get_container memory_region_get_container_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 5069d9dc..f810db59 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -2079,6 +2079,7 @@ #define memory_region_escape_name memory_region_escape_name_sparc64 #define memory_region_finalize memory_region_finalize_sparc64 #define memory_region_find memory_region_find_sparc64 +#define memory_region_from_host memory_region_from_host_sparc64 #define memory_region_get_addr memory_region_get_addr_sparc64 #define memory_region_get_alignment memory_region_get_alignment_sparc64 #define memory_region_get_container memory_region_get_container_sparc64 diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 148708bb..c0c96209 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -2079,6 +2079,7 @@ #define memory_region_escape_name memory_region_escape_name_x86_64 #define memory_region_finalize memory_region_finalize_x86_64 #define memory_region_find memory_region_find_x86_64 +#define memory_region_from_host memory_region_from_host_x86_64 #define memory_region_get_addr memory_region_get_addr_x86_64 #define memory_region_get_alignment memory_region_get_alignment_x86_64 #define memory_region_get_container memory_region_get_container_x86_64