Re: [PATCH v19 5/7] firmware: arm_rmm: Activate the RMM
flat view
From: Alper Gun <hidden>
Date: 2026-09-25 15:34:52
Also in:
kvm, kvmarm, linux-arm-kernel, lkml
Subsystem:
arm64 port (aarch64 architecture), the rest · Maintainers:
Catalin Marinas, Will Deacon, Linus Torvalds
On Fri, Sep 25, 2026 at 8:02 AM Suzuki K Poulose [off-list ref] 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@linaro.org> */ +#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;