From: Philippe Mathieu-Daudé Date: Thu, 18 Dec 2025 08:39:16 +0000 (+0100) Subject: cpus: Allocate maximum number of ASes supported by the arch X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1280ec826e98342db4e7c35daf7680d09121bde6;p=thirdparty%2Fqemu.git cpus: Allocate maximum number of ASes supported by the arch Instead of computing the number of address spaces used for a given architecture, machine, and CPU configuration, simplify the code by always allocating the maximum number of CPUAddressSpaces supported by the architecture. Signed-off-by: Gustavo Romero Reviewed-by: Pierrick Bouvier Signed-off-by: Philippe Mathieu-Daudé Message-ID: <20260116185814.108560-5-gustavo.romero@linaro.org> --- diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c index 6d54c12a77..e314f916f8 100644 --- a/hw/core/cpu-common.c +++ b/hw/core/cpu-common.c @@ -310,7 +310,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; diff --git a/hw/core/cpu-system.c b/hw/core/cpu-system.c index 48c8ddf4b1..4a91c3e8ec 100644 --- a/hw/core/cpu-system.c +++ b/hw/core/cpu-system.c @@ -86,7 +86,7 @@ int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs) if (cpu->cc->sysemu_ops->asidx_from_attrs) { ret = cpu->cc->sysemu_ops->asidx_from_attrs(cpu, attrs); - assert(ret < cpu->num_ases && ret >= 0); + assert(ret <= cpu->cc->max_as && ret >= 0); } return ret; } diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index b2e02c60d4..1eb2873460 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -51,10 +51,6 @@ void tcg_iommu_free_notifier_list(CPUState *cpu); * The target-specific code which registers ASes is responsible * for defining what semantics address space 0, 1, 2, etc have. * - * Before the first call to this function, the caller must set - * cpu->num_ases to the total number of address spaces it needs - * to support. - * * Note that with KVM only one address space is supported. */ void cpu_address_space_init(CPUState *cpu, int asidx, diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index f6f17df9e6..61da2ea433 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -145,6 +145,9 @@ struct SysemuCPUOps; * address before attempting to match it against watchpoints. * @deprecation_note: If this CPUClass is deprecated, this field provides * related information. + * @max_as: Maximum valid index used to refer to the address spaces supported by + * the architecture, i.e., to refer to CPUAddressSpaces in + * CPUState::cpu_ases. * * Represents a CPU family or model. */ @@ -195,6 +198,8 @@ struct CPUClass { int reset_dump_flags; int gdb_num_core_regs; bool gdb_stop_before_watchpoint; + + int max_as; }; /* @@ -443,7 +448,6 @@ struct qemu_work_item; * @icount_extra: Instructions until next timer event. * @cpu_ases: Pointer to array of CPUAddressSpaces (which define the * AddressSpaces this CPU has) - * @num_ases: number of CPUAddressSpaces in @cpu_ases * @as: Pointer to the first AddressSpace, for the convenience of targets which * only have a single AddressSpace * @gdb_regs: Additional GDB registers. @@ -516,7 +520,6 @@ struct CPUState { QSIMPLEQ_HEAD(, qemu_work_item) work_list; struct CPUAddressSpace *cpu_ases; - int num_ases; AddressSpace *as; MemoryRegion *memory; diff --git a/system/cpus.c b/system/cpus.c index 49deeb9468..bded87feb1 100644 --- a/system/cpus.c +++ b/system/cpus.c @@ -718,7 +718,6 @@ void qemu_init_vcpu(CPUState *cpu) /* If the target cpu hasn't set up any address spaces itself, * give it the default one. */ - 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 9a7aba9521..b0311f4531 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -786,8 +786,8 @@ void cpu_address_space_init(CPUState *cpu, int asidx, address_space_init(as, mr, as_name); g_free(as_name); - /* Target code should have set num_ases before calling us */ - assert(asidx < cpu->num_ases); + /* Target code should have set max_as before calling us */ + assert(asidx <= cpu->cc->max_as); if (asidx == 0) { /* address space 0 gets the convenience alias */ @@ -795,7 +795,7 @@ void cpu_address_space_init(CPUState *cpu, int asidx, } if (!cpu->cpu_ases) { - cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases); + cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->cc->max_as + 1); } newas = &cpu->cpu_ases[asidx]; @@ -819,7 +819,7 @@ void cpu_destroy_address_spaces(CPUState *cpu) /* convenience alias just points to some cpu_ases[n] */ cpu->as = NULL; - for (asidx = 0; asidx < cpu->num_ases; asidx++) { + for (asidx = 0; asidx <= cpu->cc->max_as; asidx++) { cpuas = &cpu->cpu_ases[asidx]; if (!cpuas->as) { /* This index was never initialized; no deinit needed */ diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 8d5987397a..6e1cbf3d61 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2149,16 +2149,6 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) unsigned int smp_cpus = ms->smp.cpus; bool has_secure = cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY); - /* - * We must set cs->num_ases to the final value before - * the first call to cpu_address_space_init. - */ - if (cpu->tag_memory != NULL) { - cs->num_ases = 3 + has_secure; - } else { - cs->num_ases = 1 + has_secure; - } - cpu_address_space_init(cs, ARMASIdx_NS, "cpu-memory", cs->memory); if (has_secure) { @@ -2392,6 +2382,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->max_as = ARMASIdx_MAX; 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 0b8cca7cec..45f0b80deb 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -10616,6 +10616,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->max_as = X86ASIdx_MAX; 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 33a8c26bc2..c34d9f15c7 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; diff --git a/target/i386/tcg/system/tcg-cpu.c b/target/i386/tcg/system/tcg-cpu.c index 7255862c24..b74e025b3e 100644 --- a/target/i386/tcg/system/tcg-cpu.c +++ b/target/i386/tcg/system/tcg-cpu.c @@ -73,7 +73,6 @@ bool tcg_cpu_realizefn(CPUState *cs, Error **errp) memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0); memory_region_set_enabled(cpu->cpu_as_mem, true); - cs->num_ases = 2; cpu_address_space_init(cs, X86ASIdx_MEM, "cpu-memory", cs->memory); cpu_address_space_init(cs, X86ASIdx_SMM, "cpu-smm", cpu->cpu_as_root);