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


Reply via email to