Re: [PATCH v19 5/7] firmware: arm_rmm: Activate the RMM
From: Alper Gun
Date: Fri Sep 25 2026 - 11:54:00 EST
On Fri, Sep 25, 2026 at 8:02 AM Suzuki K Poulose <suzuki.poulose@xxxxxxx> wrote:
[...]
> Kdump may be a bit more easier, as the kdump kernel is supposed to use
> the "reserved" region and vmcore access could handle the GPF and
> provide "0"s to the reader ? May be this is one case where the
> host needs to be able to handle GPFs.
I've tested kdump on CCA hardware with a running Realm VM and hit
GPF 0x28 in copy_oldmem_page() when reading pages delegated for
RMM/Realm metadata.
Since do_gpf() already runs fixup_exception(), using
copy_from_kernel_nofault() and falling back to iov_iter_zero() in
copy_oldmem_page() fixes it.
Here is the fix I've tested for the v16 CCA series.
diff --git a/arch/arm64/kernel/crash_dump.c b/arch/arm64/kernel/crash_dump.c
index 670e4ce81822..b0ab22293aa9 100644
--- a/arch/arm64/kernel/crash_dump.c
+++ b/arch/arm64/kernel/crash_dump.c
@@ -6,16 +6,28 @@
* Author: AKASHI Takahiro <takahiro.akashi@xxxxxxxxxx>
*/
+#include <linux/cpufeature.h>
#include <linux/crash_dump.h>
#include <linux/errno.h>
+#include <linux/gfp.h>
#include <linux/io.h>
+#include <linux/uaccess.h>
#include <linux/uio.h>
#include <asm/memory.h>
+static bool system_has_rme(void)
+{
+ u64 pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+
+ return cpuid_feature_extract_unsigned_field(pfr0,
+ ID_AA64PFR0_EL1_RME_SHIFT);
+}
+
ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
size_t csize, unsigned long offset)
{
void *vaddr;
+ void *buf;
if (!csize)
return 0;
@@ -24,8 +36,31 @@ ssize_t copy_oldmem_page(struct iov_iter *iter,
unsigned long pfn,
if (!vaddr)
return -ENOMEM;
- csize = copy_to_iter(vaddr + offset, csize, iter);
+ if (!system_has_rme()) {
+ csize = copy_to_iter(vaddr + offset, csize, iter);
+ memunmap(vaddr);
+ return csize;
+ }
+
+ buf = (void *)__get_free_page(GFP_KERNEL);
+ if (!buf) {
+ memunmap(vaddr);
+ return -ENOMEM;
+ }
+
+ /*
+ * Pages delegated to the Realm Management Monitor (RMM) or Root
+ * world trigger a synchronous Granule Protection Fault (GPF) when
+ * read from the Non-Secure crash kernel. Use copy_from_kernel_nofault()
+ * so the exception table catches the GPF and fall back to zero-filling
+ * the inaccessible granule.
+ */
+ if (copy_from_kernel_nofault(buf, vaddr + offset, csize))
+ csize = iov_iter_zero(csize, iter);
+ else
+ csize = copy_to_iter(buf, csize, iter);
+ free_page((unsigned long)buf);
memunmap(vaddr);
return csize;