diff --git a/qemu/target-arm/cpu-qom.h b/qemu/target-arm/cpu-qom.h index f9b360c2..5632fd56 100644 --- a/qemu/target-arm/cpu-qom.h +++ b/qemu/target-arm/cpu-qom.h @@ -159,6 +159,7 @@ typedef struct ARMCPU { uint64_t id_aa64mmfr1; uint32_t dbgdidr; uint32_t clidr; + uint64_t mp_affinity; /* MP ID without feature bits */ /* The elements of this array are the CCSIDR values for each cache, * in the order L1DCache, L1ICache, L2DCache, L2ICache, etc. */ diff --git a/qemu/target-arm/cpu.c b/qemu/target-arm/cpu.c index 3361c076..01c160ad 100644 --- a/qemu/target-arm/cpu.c +++ b/qemu/target-arm/cpu.c @@ -325,16 +325,28 @@ static inline void unset_feature(CPUARMState *env, int feature) env->features &= ~(1ULL << feature); } +#define ARM_CPUS_PER_CLUSTER 8 + static void arm_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque) { CPUState *cs = CPU(obj); ARMCPU *cpu = ARM_CPU(uc, obj); + uint32_t Aff1, Aff0; cs->env_ptr = &cpu->env; cpu_exec_init(&cpu->env, opaque); cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); + /* This cpu-id-to-MPIDR affinity is used only for TCG; KVM will override it. + * We don't support setting cluster ID ([16..23]) (known as Aff2 + * in later ARM ARM versions), or any of the higher affinity level fields, + * so these bits always RAZ. + */ + Aff1 = cs->cpu_index / ARM_CPUS_PER_CLUSTER; + Aff0 = cs->cpu_index % ARM_CPUS_PER_CLUSTER; + cpu->mp_affinity = (Aff1 << 8) | Aff0; + #if 0 #ifndef CONFIG_USER_ONLY /* Our inbound IRQ and FIQ lines */ diff --git a/qemu/target-arm/helper.c b/qemu/target-arm/helper.c index d0af7a25..81254eaf 100644 --- a/qemu/target-arm/helper.c +++ b/qemu/target-arm/helper.c @@ -1783,12 +1783,9 @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = { static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri) { - CPUState *cs = CPU(arm_env_get_cpu(env)); - uint32_t mpidr = cs->cpu_index; - /* We don't support setting cluster ID ([8..11]) (known as Aff1 - * in later ARM ARM versions), or any of the higher affinity level fields, - * so these bits always RAZ. - */ + ARMCPU *cpu = ARM_CPU(env->uc, arm_env_get_cpu(env)); + uint64_t mpidr = cpu->mp_affinity; + if (arm_feature(env, ARM_FEATURE_V7MP)) { mpidr |= (1U << 31); /* Cores which are uniprocessor (non-coherent)