[PATCH v14 09/44] arm64: RMI: Provide functions to delegate/undelegate ranges of memory
Marc Zyngier
maz at kernel.org
Thu May 21 06:59:34 PDT 2026
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?
Same questions for the delegation, obviously.
M.
--
Without deviation from the norm, progress is not possible.
More information about the linux-arm-kernel
mailing list