Subject: Re: [PATCH v14 04/44] arm64: RMI: Add SMC definitions for calling the RMM

From: Marc Zyngier <[email-masked]>
Date: Fri, 22 May 2026 10:58:56 +0100

On Thu, 21 May 2026 16:33:09 +0100,
Steven Price <[email-masked]> wrote:
> 
> On 21/05/2026 13:40, Marc Zyngier wrote:
> > On Wed, 13 May 2026 14:17:12 +0100,
> > Steven Price <[email-masked]> wrote:
> >>
> >> The RMM (Realm Management Monitor) provides functionality that can be
> >> accessed by SMC calls from the host.
> >>
> >> The SMC definitions are based on DEN0137[1] version 2.0-bet1
> >>
> >> [1] https://developer.arm.com/documentation/den0137/2-0bet1/
> >>
> >> Signed-off-by: Steven Price <[email-masked]>
> >> ---
> >> Changes since v13:
> >>  * Updated to RMM spec v2.0-bet1
> >> Changes since v12:
> >>  * Updated to RMM spec v2.0-bet0
> >> Changes since v9:
> >>  * Corrected size of 'ripas_value' in struct rec_exit. The spec states
> >>    this is an 8-bit type with padding afterwards (rather than a u64).
> >> Changes since v8:
> >>  * Added RMI_PERMITTED_GICV3_HCR_BITS to define which bits the RMM
> >>    permits to be modified.
> >> Changes since v6:
> >>  * Renamed REC_ENTER_xxx defines to include 'FLAG' to make it obvious
> >>    these are flag values.
> >> Changes since v5:
> >>  * Sorted the SMC #defines by value.
> >>  * Renamed SMI_RxI_CALL to SMI_RMI_CALL since the macro is only used for
> >>    RMI calls.
> >>  * Renamed REC_GIC_NUM_LRS to REC_MAX_GIC_NUM_LRS since the actual
> >>    number of available list registers could be lower.
> >>  * Provided a define for the reserved fields of FeatureRegister0.
> >>  * Fix inconsistent names for padding fields.
> >> Changes since v4:
> >>  * Update to point to final released RMM spec.
> >>  * Minor rearrangements.
> >> Changes since v3:
> >>  * Update to match RMM spec v1.0-rel0-rc1.
> >> Changes since v2:
> >>  * Fix specification link.
> >>  * Rename rec_entry->rec_enter to match spec.
> >>  * Fix size of pmu_ovf_status to match spec.
> >> ---
> >>  arch/arm64/include/asm/rmi_smc.h | 448 +++++++++++++++++++++++++++++++
> >>  1 file changed, 448 insertions(+)
> >>  create mode 100644 arch/arm64/include/asm/rmi_smc.h
> >>
> >> diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_smc.h
> >> new file mode 100644
> >> index 000000000000..a09b7a631fef
> >> --- /dev/null
> >> +++ b/arch/arm64/include/asm/rmi_smc.h
> >> @@ -0,0 +1,448 @@
> >> +/* SPDX-License-Identifier: GPL-2.0 */
> >> +/*
> >> + * Copyright (C) 2023-2026 ARM Ltd.
> >> + *
> >> + * The values and structures in this file are from the Realm Management Monitor
> >> + * specification (DEN0137) version 2.0-bet1:
> >> + * https://developer.arm.com/documentation/den0137/2-0bet1/
> > 
> > How long is this spec going to be available on the ARM web site, which
> > has a tendency of being reorganised every other week? And there is
> > already a beta2.
> 
> Obviously I can't predict the next reorganisation - but at least it's a
> link that could be fed into archive.org or similar.

I found that the PDF spec was less susceptible to creative nonsense,
and people can download it for future reference, whereas ARM has
happily *deleted* specs from the website over time (try to find PSCI
0.1, for example...).

[...]

> >> +struct realm_params {
> >> +	union { /* 0x0 */
> >> +		struct {
> >> +			u64 flags;
> >> +			u64 s2sz;
> >> +			u64 sve_vl;
> >> +			u64 num_bps;
> >> +			u64 num_wps;
> >> +			u64 pmu_num_ctrs;
> >> +			u64 hash_algo;
> >> +			u64 num_aux_planes;
> >> +		};
> >> +		u8 padding0[0x400];
> > 
> > SZ_1K? And similarly all over the shop?
> 
> I'm a bit less sure that makes the code more readable - these structures
> are a bit of a pain because they are somewhat sparse. I've left a
> comment where the beginning of each union is, and personally I find it
> easier to see 0x0 + 0x400 == 0x400 rather than trying to work out what
> SZ_1K is in hex. This is particularly the case in terms of:
> 
> > struct rec_params {
> > 	union { /* 0x0 */
> > 		u64 flags;
> > 		u8 padding0[0x100];
> > 	};
> > 	union { /* 0x100 */
> > 		u64 mpidr;
> > 		u8 padding1[0x100];
> > 	};
> > 	union { /* 0x200 */
> > 		u64 pc;
> > 		u8 padding2[0x100];
> > 	};
> > 	union { /* 0x300 */
> > 		u64 gprs[REC_CREATE_NR_GPRS];
> > 		u8 padding3[0xd00];
> > 	};
> > };
> 
> Where 0xd00 doesn't even have a correspoding SZ_ define.

Indeed, but it is (SZ_4K - SZ_256 * 3). And a lot of these structures
seem to be designed to form a 4kB blob. I'm sure we can make use of
that information (BUILD_BUG_ON?).

> 
> The RMM deals with this with macro magic:
> 
> > struct rmi_rec_params {
> >         /* Flags */
> >         SET_MEMBER_RMI(unsigned long flags, 0, 0x100);  /* Offset 0 */
> >         /* MPIDR of the REC */
> >         SET_MEMBER_RMI(unsigned long mpidr, 0x100, 0x200);      /* 0x100 */
> >         /* Program counter */
> >         SET_MEMBER_RMI(unsigned long pc, 0x200, 0x300); /* 0x200 */
> >         /* General-purpose registers */
> >         SET_MEMBER_RMI(unsigned long gprs[REC_CREATE_NR_GPRS], 0x300, 0x1000); /* 0x300 */
> > };
> 
> where the offsets are just directly encoded in the macro - but it's not
> an especially robust macro and I'm not convinced it's more readable.

I think this is just as horrible, but at least it seems to take the
boundaries of the structure into account.

>
> I'm happy to hear other suggestions on how to encode this neatly.

Honestly, I wouldn't mind having the structures described in a more
abstract way and then pre-processed to generate the include files. If
the architectural MRS wasn't so huge, I would have added it to the
kernel and used that directly for KVM.

>
> > I haven't checked the details of the encodings (life is too short),
> > but I wonder how much of this exists as an MRS and could be
> > automatically generated?
> 
> Automatically generating this would be good - I'm not sure whether we
> have a (public) source available to generate from at the moment. I have
> tried to methodically work through the spec when updating this file, but
> as Gavin has already pointed out there was at least one mistake (in
> currently unused definitions) this time.

I'm slightly baffled that even the RMM is written this way. Given the
formalism used in the RMM spec, I was expecting that you'd have a
bunch of JSON at hand and able to generate any output from that. Doing
this stuff by hand is both incredibly dull work *and* extremely error
prone.

Thanks,

	M.

-- 
Jazz isn't dead. It just smells funny.