Re: [PATCH v20 6/9] firmware: arm_rmm: Ensure the RMM has GPT entries for memory

From: Suzuki K Poulose

Date: Wed Sep 30 2026 - 13:31:54 EST


Hi Sudeep

On 30/09/2026 15:44, Sudeep Holla wrote:
On Tue, Sep 29, 2026 at 11:16:20PM +0100, Suzuki K Poulose wrote:
From: Steven Price <steven.price@xxxxxxx>

The RMM maintains the state of all the granules in the system to make
sure that the host is abiding by the rules. This state can be maintained
at different granularity, per page (TRACKING_FINE) or per region
(TRACKING_COARSE or TRACKING_INTERMEDIATE). The region size depends on the
underlying "RMI_GRANULE_SIZE". For a "coarse"/"intermediate" region,
all pages in the region must be of the same state, this implies we need to
have "fine" tracking for DRAM, so that we can delegate individual pages.

For now we only support a statically carved out memory for tracking
granules for the "fine" regions. This can be extended in the future to
allow modifying the tracking granularity and remove the need for a
static allocation by the firmware.

Similarly, the firmware may create L0 GPT entries describing the total
address space. But if we change the "PAS" (Physical Address Space) of a
granule, then the firmware may need to create L1 tables to track the PAS
at a finer granularity. Linux therefore checks if the platform firmware
manages the PAR region. i.e., the firmware is in charge of managing the
L1 GPTs (creation and the required memory for the GPT tables - via static
carveouts) without host intervention. Support for dynamic GPT creation by
the host will be added later.

If the firmware requires us to manage the tracking or GPT memory,
deactivate the RMM and reclaim any memory donated at RMM activation.

Apply the same checks when hotplugged memory is brought online.

...

---
drivers/firmware/arm_rmm/rmi.c | 247 ++++++++++++++++++++++++++++++++-
include/linux/arm-rmi-cmds.h | 18 +++
2 files changed, 264 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/arm_rmm/rmi.c b/drivers/firmware/arm_rmm/rmi.c
index d982cf158f8da..d4d098448e46e 100644
--- a/drivers/firmware/arm_rmm/rmi.c
+++ b/drivers/firmware/arm_rmm/rmi.c

[...]

+static int rmi_verify_gpt_firmware_managed(phys_addr_t start, phys_addr_t end)
+{
+ unsigned long l0gpt_sz;
+ unsigned long next, par_state;
+
+ l0gpt_sz = 1UL << (30 + FIELD_GET(RMI_FEATURE_REGISTER_1_L0GPTSZ,
+ rmi_feat_reg(1)));
+ start = ALIGN_DOWN(start, l0gpt_sz);
+ end = ALIGN(end, l0gpt_sz);
+

Is it guaranteed that end with not be = PASZ ? The spec says RMI_GPT_INFO
will return RMI_GPT_INFO when top >= pasz. Unlike start, end for good
reason is aligned up(ceil) instead of aligned down, but that also means
end will become PASZ when we reach end of memory, no ?

Good point. The RMM spec needs to be fixed to make the condition

top > pasz

as the top, is really the top the region and is not inclusive.

This is already a known issue, tracked by FENIMORE-1807. The proposed
fix is :

pre: UInt(top) > rmm.static.pasz



Sorry if I am missing something, trying to understand bits and piece of
RME still, just getting started.

Thanks for looking !

Cheers
Suzuki


+ while (start < end) {
+ long ret = rmi_gpt_info(start, end, &next, &par_state);
+
+ if (ret != RMI_SUCCESS) {
+ pr_err("RMI_GPT_INFO failed for %llx-%llx: (%ld)\n",
+ start, end, ret);
+ return -ENXIO;
+ }
+
+ if (WARN_ON(next <= start))
+ return -ENXIO;
+
+ if (par_state != RMI_GPT_PAR_PLAT) {
+ pr_err("GPT for the region is not managed by firmware %llx-%lx\n",
+ start, next);
+ return -ENODEV;
+ }
+ start = next;
+ }
+
+ return 0;
+}
+