[PATCH v14 07/44] arm64: RMI: Configure the RMM with the host's page size
Steven Price
steven.price at arm.com
Wed Jun 3 08:48:27 PDT 2026
On 21/05/2026 14:30, Marc Zyngier wrote:
> On Wed, 13 May 2026 14:17:15 +0100,
> Steven Price <steven.price at arm.com> wrote:
>>
>> RMM v2.0 brings the ability to set the RMM's granule size. Check the
>> feature registers and configure the RMM so that it matches the host's
>> page size. This means that operations can be done with a granulatity
>> equal to PAGE_SIZE.
>>
>> Signed-off-by: Steven Price <steven.price at arm.com>
>> ---
>> Changes since v13:
>> * Moved out of KVM.
>> ---
>> arch/arm64/kernel/rmi.c | 42 +++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 42 insertions(+)
>>
>> diff --git a/arch/arm64/kernel/rmi.c b/arch/arm64/kernel/rmi.c
>> index 99c1ccc35c11..a14ead5dedda 100644
>> --- a/arch/arm64/kernel/rmi.c
>> +++ b/arch/arm64/kernel/rmi.c
>> @@ -49,6 +49,45 @@ static int rmi_check_version(void)
>> return 0;
>> }
>>
>> +static int rmi_configure(void)
>> +{
>> + struct rmm_config *config __free(free_page) = NULL;
>> + unsigned long ret;
>> +
>> + config = (struct rmm_config *)get_zeroed_page(GFP_KERNEL);
>> + if (!config)
>> + return -ENOMEM;
>
> This is the sort of buggy construct that is highlighted in
> include/linux/cleanup.h: initialising the object for cleanup with
> NULL, and only later assigning the expected value.
>
> It may not matter here, but it will catch you (or more probably me) in
> the future.
Good spot. I have to admit I'm still getting the hang of these cleanup
handlers.
>> +
>> + switch (PAGE_SIZE) {
>> + case SZ_4K:
>> + config->rmi_granule_size = RMI_GRANULE_SIZE_4KB;
>> + break;
>> + case SZ_16K:
>> + config->rmi_granule_size = RMI_GRANULE_SIZE_16KB;
>> + break;
>> + case SZ_64K:
>> + config->rmi_granule_size = RMI_GRANULE_SIZE_64KB;
>> + break;
>> + default:
>> + pr_err("Unsupported PAGE_SIZE for RMM\n");
>
> Do you really anticipate PAGE_SIZE being any other value? This is 100%
> dead code. If you want to be extra cautious, have a BUILD_BUg_ON().
No, but falling through is clearly wrong (and likely to trigger AI
review comments if nothing else) - BUILD_BUG() sounds like a good solution.
>> + return -EINVAL;
>> + }
>> +
>> + ret = rmi_rmm_config_set(virt_to_phys(config));
>> + if (ret) {
>> + pr_err("RMM config set failed\n");
>> + return -EINVAL;
>> + }
>
> What is the live cycle of the page when the call succeeds? Is it
> switched back to the NS PAS and allowed to be freed?
Yes, as Suzuki answered - it never leaves the NS PAS. The RMM just reads it.
Thanks,
Steve
>> +
>> + ret = rmi_rmm_activate();
>> + if (ret) {
>> + pr_err("RMM activate failed\n");
>> + return -ENXIO;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> static int __init arm64_init_rmi(void)
>> {
>> /* Continue without realm support if we can't agree on a version */
>> @@ -60,6 +99,9 @@ static int __init arm64_init_rmi(void)
>> if (WARN_ON(rmi_features(1, &rmm_feat_reg1)))
>> return 0;
>>
>> + if (rmi_configure())
>> + return 0;
>> +
>> return 0;
>> }
>> subsys_initcall(arm64_init_rmi);
>
> Thanks,
>
> M.
>
More information about the linux-arm-kernel
mailing list