[PATCH v2 0/8] Initial implementation of kdump for ARM

Mika Westerberg ext-mika.1.westerberg at nokia.com
Wed Jul 7 03:29:38 EDT 2010


On Tue, Jul 06, 2010 at 10:30:53AM +0200, ext Per Fransson wrote:
> 
> Can't we set up the identity mapping for only the entry containing
> relocate_new_kernel() and then add enough NOPs at the start of that routine to
> cover all implementations? That way only one entry in the L1 table is
> over-written while keeping the MMU handling code in the different
> arch/arm/mm/proc-<cpu_or_arch>.S?

Did you mean something like the patch at the end of this mail? It doesn't turn
off the MMU but sets up the identity mapping for the control page only. I
quickly tested it on our platform and it seems to work:

crash> bt
PID: 1505   TASK: ddc51d40  CPU: 0   COMMAND: "sh"
 #0 [<c00890b0>] (crash_kexec) from [<c037ecd0>]
 #1 [<c037ecd0>] (panic) from [<c0030544>]
 #2 [<c0030544>] (die) from [<c0032630>]
 #3 [<c0032630>] (__do_kernel_fault) from [<c0032804>]
 #4 [<c0032804>] (do_page_fault) from [<c002c2b4>]
 #5 [<c002c2b4>] (do_DataAbort) from [<c002ca6c>]
    pc : [<c0252d74>]    lr : [<c0252f54>]    psr: 600000d3
    sp : ddca1f18  ip : 00005d75  fp : bede761c
    r10: 00000000  r9 : ddca0000  r8 : 00000007
    r7 : 00000063  r6 : 00000000  r5 : 60000053  r4 : c04e0a10
    r3 : 00000001  r2 : 00000000  r1 : 00000000  r0 : 00000063
    Flags: nZCv  IRQs off  FIQs off  Mode SVC_32  ISA ARM
 #6 [<c002ca6c>] (__dabt_svc) from [<c0252f54>]
 #7 [<c0252d74>] (sysrq_handle_crash) from [<c0252f54>]
 #8 [<c0252f54>] (__handle_sysrq) from [<c0253050>]
 #9 [<c0253050>] (write_sysrq_trigger) from [<c010e9bc>]
#10 [<c010e9bc>] (proc_reg_write) from [<c00ca0a0>]
#11 [<c00ca0a0>] (vfs_write) from [<c00ca1f4>]
#12 [<c00ca1f4>] (sys_write) from [<c002cf40>]

crash> ps -a 1505
PID: 1505   TASK: ddc51d40  CPU: 0   COMMAND: "sh"
ARG: -sh 
ENV: TERM=linux
     PATH=/sbin:/usr/sbin:/bin:/usr/bin
     USER=root
     LOGNAME=root
     HOME=/root
     SHELL=/bin/sh

So we can at least access the user stack.

However, I'm not sure what is happening with these kdump patches. If they are
going in at some point maybe we can do this stuff later on as separate patches
or should post a new version of the patches?

> Also, couldn't the L1 page table entry in question be saved for 
> posterity in a variable inside the kernel before the table is modified, 
> together with another variable to hold information on the index in the 
> table the entry came from.

Yeah, I think that we want to have full user-space mappings for post-mortem
analysis.

Regards,
MW

>From: Mika Westerberg <ext-mika.1.westerberg at nokia.com>
Subject: [PATCH] ARM: kexec: make identity mapping for control page only

With current implementation we setup 1:1 mapping for all user-space pages in
order to softboot to a new kernel. This has a drawback that we cannot access
those pages later on during post-mortem analysis.

This patch changes kexec to setup identity mapping for only the control page
(this takes 2 PMD entries) and leaves rest of the mappings intact.

Signed-off-by: Mika Westerberg <ext-mika.1.westerberg at nokia.com>
---
 arch/arm/kernel/machine_kexec.c |   42 ++++++++++++++++++++++++++++++++++++--
 1 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 81e9898..518c1ad 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -7,6 +7,7 @@
 #include <linux/delay.h>
 #include <linux/reboot.h>
 #include <linux/io.h>
+#include <asm/cputype.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
@@ -16,8 +17,6 @@
 extern const unsigned char relocate_new_kernel[];
 extern const unsigned int relocate_new_kernel_size;
 
-extern void setup_mm_for_reboot(char mode);
-
 extern unsigned long kexec_start_address;
 extern unsigned long kexec_indirection_page;
 extern unsigned long kexec_mach_type;
@@ -49,6 +48,43 @@ void machine_crash_shutdown(struct pt_regs *regs)
 	printk(KERN_INFO "Loading crashdump kernel...\n");
 }
 
+/**
+ * setup_identity_mapping() - sets up 1:1 identity mapping for a control page
+ * @phys: physical address of the control page
+ *
+ * Sets up necessary 1:1 identity mapping for user-space pages covering kexec
+ * control page. Other user-space mappings are kept intact.
+ *
+ * TODO: We could save these 2 PMD entries and restore them in
+ *       relocate_new_kernel() when we are sure that the MMU is off.
+ *       This would allow us to have complete user-space mappings
+ *       for post-mortem analysis.
+ */
+static void setup_identity_mapping(unsigned long phys)
+{
+	unsigned long pmdval = phys & PMD_MASK;
+	pgd_t *pgd;
+	pmd_t *pmd;
+
+	/*
+	 * We need to access to user-mode page tables here. For kernel threads
+	 * we don't have any user-mode mappings so we use the context that we
+	 * "borrowed".
+	 */
+	pgd = pgd_offset(current->active_mm, phys);
+	pmd = pmd_offset(pgd, phys);
+
+	pmdval |= PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
+	if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
+		pmdval |= PMD_BIT4;
+
+	pmd[0] = __pmd(pmdval);
+	pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
+
+	flush_pmd_entry(pmd);
+	local_flush_tlb_all();
+}
+
 void machine_kexec(struct kimage *image)
 {
 	unsigned long page_list;
@@ -79,6 +115,6 @@ void machine_kexec(struct kimage *image)
 	printk(KERN_INFO "Bye!\n");
 
 	cpu_proc_fin();
-	setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
+	setup_identity_mapping(reboot_code_buffer_phys);
 	cpu_reset(reboot_code_buffer_phys);
 }
-- 
1.5.6.5




More information about the linux-arm-kernel mailing list