[PATCH 3/3] arm64: kdump: add support access protection for crashkernel region

thunder.leizhen at huaweicloud.com thunder.leizhen at huaweicloud.com
Fri Jul 21 01:17:26 PDT 2023


From: Zhen Lei <thunder.leizhen at huawei.com>

arch_kexec_protect_crashkres() and arch_kexec_unprotect_crashkres()
are meant to be called by kexec_load() in order to protect the memory
allocated for crash dump kernel once the image is loaded.

This is basically revert commit 0d124e96051b
("arm64: kdump : take off the protection on crashkernel memory region"),
except for the crashkernel region has been fallen back. Because we didn't
do page-level mapping for the newly allocated region.

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 arch/arm64/include/asm/kexec.h    |  8 ++++++++
 arch/arm64/kernel/machine_kexec.c | 26 ++++++++++++++++++++++++++
 arch/arm64/mm/init.c              |  4 ++++
 3 files changed, 38 insertions(+)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 9ac9572a3bbee2c..a55388ff045e980 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -102,6 +102,14 @@ void cpu_soft_restart(unsigned long el2_switch, unsigned long entry,
 
 int machine_kexec_post_load(struct kimage *image);
 #define machine_kexec_post_load machine_kexec_post_load
+
+extern bool crash_fallback;
+
+void arch_kexec_protect_crashkres(void);
+#define arch_kexec_protect_crashkres arch_kexec_protect_crashkres
+
+void arch_kexec_unprotect_crashkres(void);
+#define arch_kexec_unprotect_crashkres arch_kexec_unprotect_crashkres
 #endif
 
 #define ARCH_HAS_KIMAGE_ARCH
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 078910db77a41b6..00392b48501d35c 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -269,6 +269,32 @@ void machine_crash_shutdown(struct pt_regs *regs)
 	pr_info("Starting crashdump kernel...\n");
 }
 
+void arch_kexec_protect_crashkres(void)
+{
+	int i;
+
+	if (crash_fallback)
+		return;
+
+	for (i = 0; i < kexec_crash_image->nr_segments; i++)
+		set_memory_valid(
+			__phys_to_virt(kexec_crash_image->segment[i].mem),
+			kexec_crash_image->segment[i].memsz >> PAGE_SHIFT, 0);
+}
+
+void arch_kexec_unprotect_crashkres(void)
+{
+	int i;
+
+	if (crash_fallback)
+		return;
+
+	for (i = 0; i < kexec_crash_image->nr_segments; i++)
+		set_memory_valid(
+			__phys_to_virt(kexec_crash_image->segment[i].mem),
+			kexec_crash_image->segment[i].memsz >> PAGE_SHIFT, 1);
+}
+
 #ifdef CONFIG_HIBERNATION
 /*
  * To preserve the crash dump kernel image, the relevant memory segments
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index d2ab377520b2742..b544ed0ab04193d 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -74,6 +74,7 @@ phys_addr_t __ro_after_init arm64_dma_phys_limit;
 
 #define DEFAULT_CRASH_KERNEL_LOW_SIZE	(128UL << 20)
 
+bool crash_fallback;
 static int crashkernel_type __initdata;
 
 static phys_addr_t __init crashkernel_phys_alloc_range(phys_addr_t size,
@@ -199,6 +200,9 @@ static void __init late_reserve_crashkernel(void)
 	crashk_res.end   = crash_base + crash_size - 1;
 	insert_resource(&iomem_resource, &crashk_res);
 
+	crash_fallback = true;
+	pr_info("cannot allocate all crashkernel memory as expected, fallen back.\n");
+
 ok:
 	crash_base = crashk_res.start;
 	crash_size = resource_size(&crashk_res);
-- 
2.25.1




More information about the linux-arm-kernel mailing list