On Fri, 16 Oct 2026 17:46:56 +0800
Jinjie Ruan <[email protected]> wrote:

> From: Jinjie Ruan <[email protected]>
> 
> FEAT_MPAM's EL2 registers were missing, so a guest kernel that owns
> or drops out of EL2 takes an UNDEFINED exception the first time it
> runs its MPAM capability enable callback, which unconditionally
> clears MPAM2_EL2 (and MPAMHCR_EL2 when HAS_HCR is present).
> 
> Register both as normal EL2 read/write registers backed by CPU state.
> 
> Signed-off-by: Jinjie Ruan <[email protected]>
> ---
>  target/arm/cpu.h    |  2 ++
>  target/arm/helper.c | 10 ++++++++++
>  2 files changed, 12 insertions(+)
> 
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 51a36fa..218923a 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -759,6 +759,8 @@ typedef struct CPUArchState {
>  
>      uint64_t mpam0_el1;
>      uint64_t mpam1_el1;
> +    uint64_t mpam2_el2;
> +    uint64_t mpamhcr_el2;
>      /* Optional fault info across tlb lookup. */
>      ARMMMUFaultInfo *tlb_fi;
>  
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index 896ac0e..d5d96d5 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -6924,6 +6924,16 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>                .accessfn = access_tid3,
>                .fieldoffset = offsetof(CPUARMState, mpam1_el1),
>              },
> +            { .name = "MPAM2_EL2", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 4, .crn = 0xa, .crm = 5, .opc2 = 0,
> +              .access = PL2_RW, .type = ARM_CP_ALIAS,

I've most forgotten how this stuff works (if I ever really knew!)
Why ARM_CP_ALIAS?  Probably just wants that dropped and provide
resetvalue = 0. 

Also, given emulation isn't yet supporting MPAM v2, there are a load
of res0 bits in here so we probably need a write mask.  There
are more complex things around what MPAM3_EL3 has in it but given
I don't think that is emulated yet, can probably just assume here
it is in it's most permissive state.

> +              .fieldoffset = offsetof(CPUARMState, mpam2_el2),
> +            },
> +            { .name = "MPAMHCR_EL2", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 4, .crn = 0xa, .crm = 4, .opc2 = 0,
> +              .access = PL2_RW, .type = ARM_CP_ALIAS,
> +              .fieldoffset = offsetof(CPUARMState, mpamhcr_el2),
> +            },
Similar for this one.

>              { .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64,
>                .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1,
>                .access = PL1_R, .type = ARM_CP_CONST,


Reply via email to