> On 29 Oct 2026, at 2:50 PM, Eric Auger <[email protected]> wrote:
> 
> !-------------------------------------------------------------------|
>  CAUTION: External Email
> 
> |-------------------------------------------------------------------!
> 
> At the moment MPIDR_EL1 has no real storage. Instead cpu
> mp_affinity field stores the Aff0-Aff2 bits only and the
> ID register is reconstructed when needed. There is also
> an mp-affinity property used for TCG only.
> 
> Keep the mp-affinity property and its associated storage
> while making sure the MPIDR_EL1 full register is stored
> in cpu->isar.idregs[] as other ID registers.
> 
> Signed-off-by: Eric Auger <[email protected]>
> Suggested-by: Khushit Shah <[email protected]>
> Reviewed-by: Peter Maydell <[email protected]>
Reviewed-by: Khushit Shah <[email protected]>

Thanks,
Khushit
> ---
> target/arm/cpu.h             |  8 +++++++-
> target/arm/cpu-sysregs.h.inc |  1 +
> target/arm/cpu.c             | 17 +++++++++++++++++
> target/arm/helper.c          | 14 +-------------
> target/arm/hvf/hvf.c         |  2 +-
> target/arm/kvm.c             |  1 +
> target/arm/whpx/whpx-all.c   |  2 +-
> 7 files changed, 29 insertions(+), 16 deletions(-)
> 
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index e6b4000127..5c5f551dac 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -1130,7 +1130,13 @@ struct ArchCPU {
>     uint32_t reset_sctlr;
>     uint64_t pmceid0;
>     uint64_t pmceid1;
> -    uint64_t mp_affinity; /* MP ID without feature bits */
> +    /*
> +     * MP ID without feature bits, ie. Aff0..Aff3 only
> +     * used to store the corresponding property value for TCG vcpus.
> +     * The MPIDR_EL1 value (affinity + feature bits) is stored in a
> +     * consistent manner in isar.idregs[MPIDR_EL1_IDX].
> +     */
> +    uint64_t mp_affinity;
>     uint64_t reset_cbar;
>     uint32_t reset_auxcr;
>     bool reset_hivecs;
> diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc
> index 709dc8fc97..f148f6f565 100644
> --- a/target/arm/cpu-sysregs.h.inc
> +++ b/target/arm/cpu-sysregs.h.inc
> @@ -42,6 +42,7 @@ DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0)
> DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1)
> DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4)
> DEF(MIDR_EL1, 3, 0, 0, 0, 0)
> +DEF(MPIDR_EL1, 3, 0, 0, 0, 5)
> DEF(MVFR0_EL1, 3, 0, 0, 3, 0)
> DEF(MVFR1_EL1, 3, 0, 0, 3, 1)
> DEF(MVFR2_EL1, 3, 0, 0, 3, 2)
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index e337462a7e..aba45b66f8 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -2170,6 +2170,23 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
> **errp)
>                                                  
> ARM_DEFAULT_CPUS_PER_CLUSTER);
>     }
> 
> +    /* Consistently update MPIDR_EL1 in isar.idregs[] by adding feature bits 
> */
> +    {
> +        uint64_t mpidr = cpu->mp_affinity;
> +
> +        if (arm_feature(env, ARM_FEATURE_V7MP)) {
> +            mpidr |= (1U << 31);
> +            /*
> +             * Uniprocessor (non-coherent) cores that still implement the MP
> +             * extensions set U (bit 30), e.g. Cortex-R5.
> +             */
> +            if (cpu->mp_is_up) {
> +                mpidr |= (1u << 30);
> +            }
> +        }
> +        SET_IDREG(&cpu->isar, MPIDR, mpidr);
> +    }
> +
>     if (cpu->reset_hivecs) {
>             cpu->reset_sctlr |= (1 << 13);
>     }
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index afaac33f2a..f413b15eb7 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -3180,20 +3180,8 @@ static uint64_t midr_read(CPUARMState *env, const 
> ARMCPRegInfo *ri)
> static uint64_t mpidr_read_val(CPUARMState *env)
> {
>     ARMCPU *cpu = env_archcpu(env);
> -    uint64_t mpidr = cpu->mp_affinity;
> 
> -    if (arm_feature(env, ARM_FEATURE_V7MP)) {
> -        mpidr |= (1U << 31);
> -        /*
> -         * Cores which are uniprocessor (non-coherent)
> -         * but still implement the MP extensions set
> -         * bit 30. (For instance, Cortex-R5).
> -         */
> -        if (cpu->mp_is_up) {
> -            mpidr |= (1u << 30);
> -        }
> -    }
> -    return mpidr;
> +    return GET_IDREG(&cpu->isar, MPIDR);
> }
> 
> static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
> diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
> index f9f3d22014..4b947e9ba5 100644
> --- a/target/arm/hvf/hvf.c
> +++ b/target/arm/hvf/hvf.c
> @@ -1476,7 +1476,7 @@ int hvf_arch_init_vcpu(CPUState *cpu)
>     assert_hvf_ok(ret);
> 
>     ret = hv_vcpu_set_sys_reg(cpu->accel->fd, HV_SYS_REG_MPIDR_EL1,
> -                              arm_cpu->mp_affinity);
> +                              GET_IDREG(&arm_cpu->isar, MPIDR));
>     assert_hvf_ok(ret);
> 
>     pfr = GET_IDREG(&arm_cpu->isar, ID_AA64PFR0);
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index de09d63d2e..724bc08edf 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -2103,6 +2103,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
>     if (ret) {
>         return ret;
>     }
> +    SET_IDREG(&cpu->isar, MPIDR, mpidr);
>     cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
> 
>     return kvm_arm_init_cpreg_list(cpu);
> diff --git a/target/arm/whpx/whpx-all.c b/target/arm/whpx/whpx-all.c
> index 18009d6c8d..024d18df04 100644
> --- a/target/arm/whpx/whpx-all.c
> +++ b/target/arm/whpx/whpx-all.c
> @@ -842,7 +842,7 @@ int whpx_init_vcpu(CPUState *cpu)
> 
>     clean_whv_register_value(&val);
> 
> -    val.Reg64 = deposit64(arm_cpu->mp_affinity, 31, 1, 1 /* RES1 */);
> +    val.Reg64 = GET_IDREG(&arm_cpu->isar, MPIDR);
>     whpx_set_reg(cpu, WHvArm64RegisterMpidrEl1, val);
> 
>     clamp_id_aa64mmfr0_parange_to_ipa_size(&arm_cpu->isar);
> -- 
> 2.53.0
> 

Reply via email to