[PATCH v14 09/44] arm64: RMI: Provide functions to delegate/undelegate ranges of memory
Marc Zyngier
maz at kernel.org
Fri May 22 03:02:20 PDT 2026
On Thu, 21 May 2026 17:01:37 +0100,
Suzuki K Poulose <suzuki.poulose at arm.com> wrote:
>
> On 21/05/2026 14:59, Marc Zyngier wrote:
> > On Wed, 13 May 2026 14:17:17 +0100,
> > Steven Price <steven.price at arm.com> wrote:
> >>
> >> The RMM requires memory is 'delegated' to it so that it can be used
> >> either for a realm guest or for various tracking purposes within the RMM
> >> (e.g. for metadata or page tables). Memory that has been delegated
> >> cannot be accessed by the host (it will result in a Granule Protection
> >> Fault).
> >>
> >> Undelegation may fail if the memory is still in use by the RMM. This
> >> shouldn't happen (Linux should ensure it has destroyed the RMM objects
> >> before attempting to undelegate). In the event that it does happen this
> >> points to a programming bug and the only reasonable approach is for the
> >> physical pages to be leaked - it is up to the caller of
> >> rmi_undelegate_range() to handle this.
> >>
> >> Signed-off-by: Steven Price <steven.price at arm.com>
> >> ---
> >> v14:
> >> * Split into separate patch and moved out of KVM
> >> ---
> >> arch/arm64/include/asm/rmi_cmds.h | 13 +++++++++++
> >> arch/arm64/kernel/rmi.c | 36 +++++++++++++++++++++++++++++++
> >> 2 files changed, 49 insertions(+)
> >>
> >> diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi_cmds.h
> >> index 9078a2920a7c..eb213c8e6f26 100644
> >> --- a/arch/arm64/include/asm/rmi_cmds.h
> >> +++ b/arch/arm64/include/asm/rmi_cmds.h
> >> @@ -33,6 +33,19 @@ struct rmi_sro_state {
> >> } while (RMI_RETURN_STATUS(res.a0) == RMI_BUSY || \
> >> RMI_RETURN_STATUS(res.a0) == RMI_BLOCKED)
> >> +int rmi_delegate_range(phys_addr_t phys, unsigned long size);
> >> +int rmi_undelegate_range(phys_addr_t phys, unsigned long size);
> >> +
> >> +static inline int rmi_delegate_page(phys_addr_t phys)
> >> +{
> >> + return rmi_delegate_range(phys, PAGE_SIZE);
> >> +}
> >> +
> >> +static inline int rmi_undelegate_page(phys_addr_t phys)
> >> +{
> >> + return rmi_undelegate_range(phys, PAGE_SIZE);
> >> +}
> >> +
> >> bool rmi_is_available(void);
> >> unsigned long rmi_sro_execute(struct rmi_sro_state *sro, gfp_t
> >> gfp);
> >> diff --git a/arch/arm64/kernel/rmi.c b/arch/arm64/kernel/rmi.c
> >> index 52a415e99500..08cef54acadb 100644
> >> --- a/arch/arm64/kernel/rmi.c
> >> +++ b/arch/arm64/kernel/rmi.c
> >> @@ -12,6 +12,42 @@ static bool arm64_rmi_is_available;
> >> unsigned long rmm_feat_reg0;
> >> unsigned long rmm_feat_reg1;
> >> +int rmi_delegate_range(phys_addr_t phys, unsigned long size)
> >> +{
> >> + unsigned long ret = 0;
> >> + unsigned long top = phys + size;
> >> + unsigned long out_top;
> >> +
> >> + while (phys < top) {
> >> + ret = rmi_granule_range_delegate(phys, top, &out_top);
> >> + if (ret == RMI_SUCCESS)
> >> + phys = out_top;
> >> + else if (ret != RMI_BUSY && ret != RMI_BLOCKED)
> >> + return ret;
> >> + }
> >> +
> >> + return ret;
> >> +}
> >> +
> >> +int rmi_undelegate_range(phys_addr_t phys, unsigned long size)
> >> +{
> >> + unsigned long ret = 0;
> >> + unsigned long top = phys + size;
> >> + unsigned long out_top;
> >> +
> >> + WARN_ON(size == 0);
> >
> > I find it odd to warn on size = 0. After all, free(NULL) is not an
> > error. But even then, you continue feeding this to the RMM.
> >
> > You also don't seem to be bothered with that on the delegation side...
> >
> >> +
> >> + while (phys < top) {
> >> + ret = rmi_granule_range_undelegate(phys, top, &out_top);
> >> + if (ret == RMI_SUCCESS)
> >> + phys = out_top;
> >
> > and size==0 doesn't violate any of the failure conditions listed in
> > B4.5.18.2 (beta2). Will you end-up looping around forever?
>
> That is not true ? It triggers, top_bound error condition, for both.
>
>
> pre: UInt(top) <= UInt(base)
> post: result.status == RMI_ERROR_INPUT
News flash, I can't read. Ignore me.
M.
--
Jazz isn't dead. It just smells funny.
More information about the linux-arm-kernel
mailing list