diff --git a/qemu/aarch64.h b/qemu/aarch64.h index f62d843d..521aef26 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -47,6 +47,7 @@ #define tcg_enabled tcg_enabled_aarch64 #define tcg_exec_init tcg_exec_init_aarch64 #define memory_register_types memory_register_types_aarch64 +#define cpu_address_space_init cpu_address_space_init_aarch64 #define cpu_exec_init_all cpu_exec_init_all_aarch64 #define cpu_reload_memory_map cpu_reload_memory_map_aarch64 #define vm_start vm_start_aarch64 @@ -2733,7 +2734,6 @@ #define tcg_const_local_i32 tcg_const_local_i32_aarch64 #define tcg_const_local_i64 tcg_const_local_i64_aarch64 #define tcg_context_init tcg_context_init_aarch64 -#define tcg_cpu_address_space_init tcg_cpu_address_space_init_aarch64 #define tcg_cpu_exec tcg_cpu_exec_aarch64 #define tcg_current_code_size tcg_current_code_size_aarch64 #define tcg_dump_info tcg_dump_info_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 53740fd1..2092b9e9 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -47,6 +47,7 @@ #define tcg_enabled tcg_enabled_aarch64eb #define tcg_exec_init tcg_exec_init_aarch64eb #define memory_register_types memory_register_types_aarch64eb +#define cpu_address_space_init cpu_address_space_init_aarch64eb #define cpu_exec_init_all cpu_exec_init_all_aarch64eb #define cpu_reload_memory_map cpu_reload_memory_map_aarch64eb #define vm_start vm_start_aarch64eb @@ -2733,7 +2734,6 @@ #define tcg_const_local_i32 tcg_const_local_i32_aarch64eb #define tcg_const_local_i64 tcg_const_local_i64_aarch64eb #define tcg_context_init tcg_context_init_aarch64eb -#define tcg_cpu_address_space_init tcg_cpu_address_space_init_aarch64eb #define tcg_cpu_exec tcg_cpu_exec_aarch64eb #define tcg_current_code_size tcg_current_code_size_aarch64eb #define tcg_dump_info tcg_dump_info_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 2873853e..b4e4785f 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -47,6 +47,7 @@ #define tcg_enabled tcg_enabled_arm #define tcg_exec_init tcg_exec_init_arm #define memory_register_types memory_register_types_arm +#define cpu_address_space_init cpu_address_space_init_arm #define cpu_exec_init_all cpu_exec_init_all_arm #define cpu_reload_memory_map cpu_reload_memory_map_arm #define vm_start vm_start_arm @@ -2733,7 +2734,6 @@ #define tcg_const_local_i32 tcg_const_local_i32_arm #define tcg_const_local_i64 tcg_const_local_i64_arm #define tcg_context_init tcg_context_init_arm -#define tcg_cpu_address_space_init tcg_cpu_address_space_init_arm #define tcg_cpu_exec tcg_cpu_exec_arm #define tcg_current_code_size tcg_current_code_size_arm #define tcg_dump_info tcg_dump_info_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 97af51db..3bd6faf2 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -47,6 +47,7 @@ #define tcg_enabled tcg_enabled_armeb #define tcg_exec_init tcg_exec_init_armeb #define memory_register_types memory_register_types_armeb +#define cpu_address_space_init cpu_address_space_init_armeb #define cpu_exec_init_all cpu_exec_init_all_armeb #define cpu_reload_memory_map cpu_reload_memory_map_armeb #define vm_start vm_start_armeb @@ -2733,7 +2734,6 @@ #define tcg_const_local_i32 tcg_const_local_i32_armeb #define tcg_const_local_i64 tcg_const_local_i64_armeb #define tcg_context_init tcg_context_init_armeb -#define tcg_cpu_address_space_init tcg_cpu_address_space_init_armeb #define tcg_cpu_exec tcg_cpu_exec_armeb #define tcg_current_code_size tcg_current_code_size_armeb #define tcg_dump_info tcg_dump_info_armeb diff --git a/qemu/cpus.c b/qemu/cpus.c index 69aa2d83..8f5835c2 100644 --- a/qemu/cpus.c +++ b/qemu/cpus.c @@ -110,7 +110,12 @@ static void *qemu_tcg_cpu_loop(struct uc_struct *uc) static int qemu_tcg_init_vcpu(CPUState *cpu) { - tcg_cpu_address_space_init(cpu, cpu->as); + if (!cpu->as) { + /* If the target cpu hasn't set up any address spaces itself, + * give it the default one. + */ + cpu_address_space_init(cpu, &cpu->uc->as, 0); + } return 0; } diff --git a/qemu/exec.c b/qemu/exec.c index d5445694..e92ec6a4 100644 --- a/qemu/exec.c +++ b/qemu/exec.c @@ -383,18 +383,28 @@ CPUState *qemu_get_cpu(struct uc_struct *uc, int index) } #if !defined(CONFIG_USER_ONLY) -void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as) +void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx) { + if (asidx == 0) { + /* address space 0 gets the convenience alias */ + cpu->as = as; + } + /* We only support one address space per cpu at the moment. */ assert(cpu->as == as); - if (cpu->tcg_as_listener) { - memory_listener_unregister(as->uc, cpu->tcg_as_listener); - } else { - cpu->tcg_as_listener = g_new0(MemoryListener, 1); + if (cpu->cpu_ases) { + /* We've already registered the listener for our only AS */ + return; + } + + cpu->cpu_ases = g_new0(CPUAddressSpace, 1); + cpu->cpu_ases[0].cpu = cpu; + cpu->cpu_ases[0].as = as; + if (tcg_enabled(as->uc)) { + cpu->cpu_ases[0].tcg_as_listener.commit = tcg_commit; + memory_listener_register(as->uc, &cpu->cpu_ases[0].tcg_as_listener, as); } - cpu->tcg_as_listener->commit = tcg_commit; - memory_listener_register(as->uc, cpu->tcg_as_listener, as); } #endif @@ -403,12 +413,11 @@ void cpu_exec_init(CPUState *cpu, void *opaque) struct uc_struct *uc = opaque; CPUArchState *env = cpu->env_ptr; + cpu->cpu_index = 0; + cpu->as = NULL; cpu->uc = uc; env->uc = uc; - cpu->cpu_index = 0; - cpu->as = &uc->as; - // TODO: assert uc does not already have a cpu? uc->cpu = cpu; } diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 6ceffe67..fe4acd68 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -53,6 +53,7 @@ symbols = ( 'tcg_enabled', 'tcg_exec_init', 'memory_register_types', + 'cpu_address_space_init', 'cpu_exec_init_all', 'cpu_reload_memory_map', 'vm_start', @@ -2739,7 +2740,6 @@ symbols = ( 'tcg_const_local_i32', 'tcg_const_local_i64', 'tcg_context_init', - 'tcg_cpu_address_space_init', 'tcg_cpu_exec', 'tcg_current_code_size', 'tcg_dump_info', diff --git a/qemu/include/exec/exec-all.h b/qemu/include/exec/exec-all.h index 30700c39..ae9770ec 100644 --- a/qemu/include/exec/exec-all.h +++ b/qemu/include/exec/exec-all.h @@ -83,7 +83,21 @@ void QEMU_NORETURN cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc); #if !defined(CONFIG_USER_ONLY) void cpu_reload_memory_map(CPUState *cpu); -void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as); +/** + * cpu_address_space_init: + * @cpu: CPU to add this address space to + * @as: address space to add + * @asidx: integer index of this address space + * + * Add the specified address space to the CPU's cpu_ases list. + * The address space added with @asidx 0 is the one used for the + * convenience pointer cpu->as. + * The target-specific code which registers ASes is responsible + * for defining what semantics address space 0, 1, 2, etc have. + * + * Note that with KVM only one address space is supported. + */ +void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx); /* cputlb.c */ /** * tlb_flush_page: diff --git a/qemu/include/qemu/typedefs.h b/qemu/include/qemu/typedefs.h index 6fb72bad..c9cad003 100644 --- a/qemu/include/qemu/typedefs.h +++ b/qemu/include/qemu/typedefs.h @@ -15,6 +15,7 @@ typedef struct BusClass BusClass; typedef struct BusState BusState; typedef struct CharDriverState CharDriverState; typedef struct CompatProperty CompatProperty; +typedef struct CPUAddressSpace CPUAddressSpace; typedef struct DeviceState DeviceState; typedef struct DisplayChangeListener DisplayChangeListener; typedef struct DisplayState DisplayState; diff --git a/qemu/include/qom/cpu.h b/qemu/include/qom/cpu.h index a67b4041..3b27dad3 100644 --- a/qemu/include/qom/cpu.h +++ b/qemu/include/qom/cpu.h @@ -24,6 +24,7 @@ #include #include "hw/qdev-core.h" #include "exec/hwaddr.h" +#include "exec/memory.h" #include "qemu/queue.h" #include "qemu/thread.h" #include "qemu/typedefs.h" @@ -171,6 +172,21 @@ struct kvm_run; #define TB_JMP_CACHE_BITS 12 #define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS) +// Unicorn: Moved CPUAddressSpace here from exec.c +/** + * CPUAddressSpace: all the information a CPU needs about an AddressSpace + * @cpu: the CPU whose AddressSpace this is + * @as: the AddressSpace itself + * @memory_dispatch: its dispatch pointer (cached, RCU protected) + * @tcg_as_listener: listener for tracking changes to the AddressSpace + */ +struct CPUAddressSpace { + CPUState *cpu; + AddressSpace *as; + struct AddressSpaceDispatch *memory_dispatch; + MemoryListener tcg_as_listener; +}; + /** * CPUState: * @cpu_index: CPU index (informative). @@ -231,9 +247,10 @@ struct CPUState { int64_t icount_extra; sigjmp_buf jmp_env; + CPUAddressSpace *cpu_ases; + int num_ases; AddressSpace *as; struct AddressSpaceDispatch *memory_dispatch; - MemoryListener *tcg_as_listener; void *env_ptr; /* CPUArchState */ struct TranslationBlock *current_tb; diff --git a/qemu/m68k.h b/qemu/m68k.h index b8c454ff..2093586e 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -47,6 +47,7 @@ #define tcg_enabled tcg_enabled_m68k #define tcg_exec_init tcg_exec_init_m68k #define memory_register_types memory_register_types_m68k +#define cpu_address_space_init cpu_address_space_init_m68k #define cpu_exec_init_all cpu_exec_init_all_m68k #define cpu_reload_memory_map cpu_reload_memory_map_m68k #define vm_start vm_start_m68k @@ -2733,7 +2734,6 @@ #define tcg_const_local_i32 tcg_const_local_i32_m68k #define tcg_const_local_i64 tcg_const_local_i64_m68k #define tcg_context_init tcg_context_init_m68k -#define tcg_cpu_address_space_init tcg_cpu_address_space_init_m68k #define tcg_cpu_exec tcg_cpu_exec_m68k #define tcg_current_code_size tcg_current_code_size_m68k #define tcg_dump_info tcg_dump_info_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 31cbac48..e3ad3df8 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -47,6 +47,7 @@ #define tcg_enabled tcg_enabled_mips #define tcg_exec_init tcg_exec_init_mips #define memory_register_types memory_register_types_mips +#define cpu_address_space_init cpu_address_space_init_mips #define cpu_exec_init_all cpu_exec_init_all_mips #define cpu_reload_memory_map cpu_reload_memory_map_mips #define vm_start vm_start_mips @@ -2733,7 +2734,6 @@ #define tcg_const_local_i32 tcg_const_local_i32_mips #define tcg_const_local_i64 tcg_const_local_i64_mips #define tcg_context_init tcg_context_init_mips -#define tcg_cpu_address_space_init tcg_cpu_address_space_init_mips #define tcg_cpu_exec tcg_cpu_exec_mips #define tcg_current_code_size tcg_current_code_size_mips #define tcg_dump_info tcg_dump_info_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 779c0eb8..09ea84e4 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -47,6 +47,7 @@ #define tcg_enabled tcg_enabled_mips64 #define tcg_exec_init tcg_exec_init_mips64 #define memory_register_types memory_register_types_mips64 +#define cpu_address_space_init cpu_address_space_init_mips64 #define cpu_exec_init_all cpu_exec_init_all_mips64 #define cpu_reload_memory_map cpu_reload_memory_map_mips64 #define vm_start vm_start_mips64 @@ -2733,7 +2734,6 @@ #define tcg_const_local_i32 tcg_const_local_i32_mips64 #define tcg_const_local_i64 tcg_const_local_i64_mips64 #define tcg_context_init tcg_context_init_mips64 -#define tcg_cpu_address_space_init tcg_cpu_address_space_init_mips64 #define tcg_cpu_exec tcg_cpu_exec_mips64 #define tcg_current_code_size tcg_current_code_size_mips64 #define tcg_dump_info tcg_dump_info_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 4ea7f7ad..38cabdce 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -47,6 +47,7 @@ #define tcg_enabled tcg_enabled_mips64el #define tcg_exec_init tcg_exec_init_mips64el #define memory_register_types memory_register_types_mips64el +#define cpu_address_space_init cpu_address_space_init_mips64el #define cpu_exec_init_all cpu_exec_init_all_mips64el #define cpu_reload_memory_map cpu_reload_memory_map_mips64el #define vm_start vm_start_mips64el @@ -2733,7 +2734,6 @@ #define tcg_const_local_i32 tcg_const_local_i32_mips64el #define tcg_const_local_i64 tcg_const_local_i64_mips64el #define tcg_context_init tcg_context_init_mips64el -#define tcg_cpu_address_space_init tcg_cpu_address_space_init_mips64el #define tcg_cpu_exec tcg_cpu_exec_mips64el #define tcg_current_code_size tcg_current_code_size_mips64el #define tcg_dump_info tcg_dump_info_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index c475562c..a595ef8b 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -47,6 +47,7 @@ #define tcg_enabled tcg_enabled_mipsel #define tcg_exec_init tcg_exec_init_mipsel #define memory_register_types memory_register_types_mipsel +#define cpu_address_space_init cpu_address_space_init_mipsel #define cpu_exec_init_all cpu_exec_init_all_mipsel #define cpu_reload_memory_map cpu_reload_memory_map_mipsel #define vm_start vm_start_mipsel @@ -2733,7 +2734,6 @@ #define tcg_const_local_i32 tcg_const_local_i32_mipsel #define tcg_const_local_i64 tcg_const_local_i64_mipsel #define tcg_context_init tcg_context_init_mipsel -#define tcg_cpu_address_space_init tcg_cpu_address_space_init_mipsel #define tcg_cpu_exec tcg_cpu_exec_mipsel #define tcg_current_code_size tcg_current_code_size_mipsel #define tcg_dump_info tcg_dump_info_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 17c721b5..7a2d7474 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -47,6 +47,7 @@ #define tcg_enabled tcg_enabled_powerpc #define tcg_exec_init tcg_exec_init_powerpc #define memory_register_types memory_register_types_powerpc +#define cpu_address_space_init cpu_address_space_init_powerpc #define cpu_exec_init_all cpu_exec_init_all_powerpc #define cpu_reload_memory_map cpu_reload_memory_map_powerpc #define vm_start vm_start_powerpc @@ -2733,7 +2734,6 @@ #define tcg_const_local_i32 tcg_const_local_i32_powerpc #define tcg_const_local_i64 tcg_const_local_i64_powerpc #define tcg_context_init tcg_context_init_powerpc -#define tcg_cpu_address_space_init tcg_cpu_address_space_init_powerpc #define tcg_cpu_exec tcg_cpu_exec_powerpc #define tcg_current_code_size tcg_current_code_size_powerpc #define tcg_dump_info tcg_dump_info_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index b7e884a0..5e6f162d 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -47,6 +47,7 @@ #define tcg_enabled tcg_enabled_sparc #define tcg_exec_init tcg_exec_init_sparc #define memory_register_types memory_register_types_sparc +#define cpu_address_space_init cpu_address_space_init_sparc #define cpu_exec_init_all cpu_exec_init_all_sparc #define cpu_reload_memory_map cpu_reload_memory_map_sparc #define vm_start vm_start_sparc @@ -2733,7 +2734,6 @@ #define tcg_const_local_i32 tcg_const_local_i32_sparc #define tcg_const_local_i64 tcg_const_local_i64_sparc #define tcg_context_init tcg_context_init_sparc -#define tcg_cpu_address_space_init tcg_cpu_address_space_init_sparc #define tcg_cpu_exec tcg_cpu_exec_sparc #define tcg_current_code_size tcg_current_code_size_sparc #define tcg_dump_info tcg_dump_info_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index c280330b..9d395e1d 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -47,6 +47,7 @@ #define tcg_enabled tcg_enabled_sparc64 #define tcg_exec_init tcg_exec_init_sparc64 #define memory_register_types memory_register_types_sparc64 +#define cpu_address_space_init cpu_address_space_init_sparc64 #define cpu_exec_init_all cpu_exec_init_all_sparc64 #define cpu_reload_memory_map cpu_reload_memory_map_sparc64 #define vm_start vm_start_sparc64 @@ -2733,7 +2734,6 @@ #define tcg_const_local_i32 tcg_const_local_i32_sparc64 #define tcg_const_local_i64 tcg_const_local_i64_sparc64 #define tcg_context_init tcg_context_init_sparc64 -#define tcg_cpu_address_space_init tcg_cpu_address_space_init_sparc64 #define tcg_cpu_exec tcg_cpu_exec_sparc64 #define tcg_current_code_size tcg_current_code_size_sparc64 #define tcg_dump_info tcg_dump_info_sparc64 diff --git a/qemu/target-i386/cpu.c b/qemu/target-i386/cpu.c index 7a33357f..ffd3c8cc 100644 --- a/qemu/target-i386/cpu.c +++ b/qemu/target-i386/cpu.c @@ -2601,12 +2601,14 @@ static int x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err #ifndef CONFIG_USER_ONLY if (tcg_enabled(uc)) { + AddressSpace *newas = g_new(AddressSpace, 1); + cpu->cpu_as_root = g_new(MemoryRegion, 1); - cs->as = g_new(AddressSpace, 1); memory_region_init_alias(uc, cpu->cpu_as_root, OBJECT(cpu), "memory", get_system_memory(uc), 0, ~0ull); memory_region_set_enabled(cpu->cpu_as_root, true); - address_space_init(uc, cs->as, cpu->cpu_as_root, "CPU"); + address_space_init(uc, newas, cpu->cpu_as_root, "CPU"); + cpu_address_space_init(cs, newas, 0); } #endif diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 59e9518c..dd5f6b58 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -47,6 +47,7 @@ #define tcg_enabled tcg_enabled_x86_64 #define tcg_exec_init tcg_exec_init_x86_64 #define memory_register_types memory_register_types_x86_64 +#define cpu_address_space_init cpu_address_space_init_x86_64 #define cpu_exec_init_all cpu_exec_init_all_x86_64 #define cpu_reload_memory_map cpu_reload_memory_map_x86_64 #define vm_start vm_start_x86_64 @@ -2733,7 +2734,6 @@ #define tcg_const_local_i32 tcg_const_local_i32_x86_64 #define tcg_const_local_i64 tcg_const_local_i64_x86_64 #define tcg_context_init tcg_context_init_x86_64 -#define tcg_cpu_address_space_init tcg_cpu_address_space_init_x86_64 #define tcg_cpu_exec tcg_cpu_exec_x86_64 #define tcg_current_code_size tcg_current_code_size_x86_64 #define tcg_dump_info tcg_dump_info_x86_64 diff --git a/uc.c b/uc.c index ef5ef23c..8230d2a7 100644 --- a/uc.c +++ b/uc.c @@ -293,7 +293,7 @@ uc_err uc_close(uc_engine *uc) g_free(uc->tcg_ctx); // Cleanup CPU. - g_free(uc->cpu->tcg_as_listener); + g_free(uc->cpu->cpu_ases); g_free(uc->cpu->thread); // Cleanup all objects.