From: Philippe Mathieu-Daudé <[email protected]> Define upfront in CPUClass the total number of address spaces a CPU can use rather than allocating it on-demand in cpu_address_space_init() by allocating it in cpu_exec_initfn() and always releasing it in cpu_common_finalize().
Signed-off-by: Philippe Mathieu-Daudé <[email protected]> Signed-off-by: Gustavo Romero <[email protected]> --- hw/core/cpu-common.c | 2 +- hw/core/cpu-system.c | 6 ------ include/hw/core/cpu.h | 3 +++ system/cpus.c | 7 ++++--- system/physmem.c | 22 ++++++++++++++++------ target/arm/cpu.c | 1 + target/i386/cpu.c | 1 + target/i386/kvm/kvm-cpu.c | 1 - 8 files changed, 26 insertions(+), 17 deletions(-) diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c index 8c306c89e4..2921d07506 100644 --- a/hw/core/cpu-common.c +++ b/hw/core/cpu-common.c @@ -309,7 +309,6 @@ static void cpu_common_initfn(Object *obj) cpu->cpu_index = UNASSIGNED_CPU_INDEX; cpu->cluster_index = UNASSIGNED_CLUSTER_INDEX; cpu->as = NULL; - cpu->num_ases = 0; /* user-mode doesn't have configurable SMP topology */ /* the default value is changed by qemu_init_vcpu() for system-mode */ cpu->nr_threads = 1; @@ -359,6 +358,7 @@ static void cpu_common_finalize(Object *obj) qemu_cond_destroy(cpu->halt_cond); g_free(cpu->halt_cond); g_free(cpu->thread); + g_free(cpu->cpu_ases); } static int64_t cpu_common_get_arch_id(CPUState *cpu) diff --git a/hw/core/cpu-system.c b/hw/core/cpu-system.c index f601a083d1..b6a290b648 100644 --- a/hw/core/cpu-system.c +++ b/hw/core/cpu-system.c @@ -188,12 +188,6 @@ void cpu_exec_class_post_init(CPUClass *cc) g_assert(cc->sysemu_ops->has_work); } -void cpu_exec_initfn(CPUState *cpu) -{ - cpu->memory = get_system_memory(); - object_ref(OBJECT(cpu->memory)); -} - static int cpu_common_post_load(void *opaque, int version_id) { if (tcg_enabled()) { diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 9615051774..f88a5729e7 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -145,6 +145,7 @@ struct SysemuCPUOps; * address before attempting to match it against watchpoints. * @deprecation_note: If this CPUClass is deprecated, this field provides * related information. + * @num_ases: Total number of address spaces usable by the architecture. * * Represents a CPU family or model. */ @@ -195,6 +196,8 @@ struct CPUClass { int reset_dump_flags; int gdb_num_core_regs; bool gdb_stop_before_watchpoint; + /* Total number of address spaces. */ + unsigned num_ases; }; /* diff --git a/system/cpus.c b/system/cpus.c index ef2d2f241f..638e558153 100644 --- a/system/cpus.c +++ b/system/cpus.c @@ -715,10 +715,11 @@ void qemu_init_vcpu(CPUState *cpu) cpu->random_seed = qemu_guest_random_seed_thread_part1(); if (!cpu->as) { - /* If the target cpu hasn't set up any address spaces itself, - * give it the default one. + /* + * If the target has not set up the address space 0 (main memory), + * set it. Address space 0 is special and has an alias kept in + * cpu->as. If address space 0 is set up cpu->as is always != NULL. */ - cpu->num_ases = 1; cpu_address_space_init(cpu, 0, "cpu-memory", cpu->memory); } diff --git a/system/physmem.c b/system/physmem.c index c9869e4049..c06bd5ce06 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -775,6 +775,22 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu, #endif /* CONFIG_TCG */ +void cpu_exec_initfn(CPUState *cpu) +{ + + /* + * If the total number of address spaces for CPUs is not defined explicitly + * by the arch the default is 1 address space. + */ + unsigned num_ases = cpu->cc->num_ases ? cpu->cc->num_ases : 1; + + cpu->cpu_ases = g_new0(CPUAddressSpace, num_ases); + cpu->num_ases = num_ases; + + cpu->memory = get_system_memory(); + object_ref(OBJECT(cpu->memory)); +} + void cpu_address_space_init(CPUState *cpu, int asidx, const char *prefix, MemoryRegion *mr) { @@ -795,10 +811,6 @@ void cpu_address_space_init(CPUState *cpu, int asidx, cpu->as = as; } - if (!cpu->cpu_ases) { - cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases); - } - newas = &cpu->cpu_ases[asidx]; newas->cpu = cpu; newas->as = as; @@ -831,8 +843,6 @@ void cpu_destroy_address_spaces(CPUState *cpu) } g_clear_pointer(&cpuas->as, address_space_destroy_free); } - - g_clear_pointer(&cpu->cpu_ases, g_free); } AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 1640b20b4d..cd73991f9f 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2391,6 +2391,7 @@ static void arm_cpu_class_init(ObjectClass *oc, const void *data) cc->gdb_read_register = arm_cpu_gdb_read_register; cc->gdb_write_register = arm_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY + cc->num_ases = ARMASIdx_COUNT; cc->sysemu_ops = &arm_sysemu_ops; #endif cc->gdb_arch_name = arm_gdb_arch_name; diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 6417775786..5f6fc176fd 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -10106,6 +10106,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, const void *data) cc->get_arch_id = x86_cpu_get_arch_id; #ifndef CONFIG_USER_ONLY + cc->num_ases = X86ASIdx_COUNT; cc->sysemu_ops = &i386_sysemu_ops; #endif /* !CONFIG_USER_ONLY */ #ifdef CONFIG_TCG diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c index 9c25b55839..855edd164d 100644 --- a/target/i386/kvm/kvm-cpu.c +++ b/target/i386/kvm/kvm-cpu.c @@ -98,7 +98,6 @@ static bool kvm_cpu_realizefn(CPUState *cs, Error **errp) * Only initialize address space 0 here, the second one for SMM is * initialized at register_smram_listener() after machine init done. */ - cs->num_ases = x86_machine_is_smm_enabled(X86_MACHINE(current_machine)) ? 2 : 1; cpu_address_space_init(cs, X86ASIdx_MEM, "cpu-memory", cs->memory); return true; -- 2.34.1
