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,
