[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <w4fwgnhkcd.wl%peter@chubb.wattle.id.au>
Date: Wed, 14 Dec 2011 15:02:10 +1100
From: Peter Chubb <peter.chubb@...ta.com.au>
To: linux-kernel@...r.kernel.org, linux@....linux.org.uk,
kexec@...ts.infradead.org
Subject: [PATCH] Fix kexec reboot on ARM
When kexec() runs, it eventually sets up a 1-to-1 memory map, then
invokes cpu_reset(). When it invokes cpu_reset (which turns
off the MMU), it does so at its virtual address. Across the code that
disables the MMU, virtual and physical addresses have to be the same,
otherwise after disabling the MMU, the PC is invalid.
The simplest fix is to invoke cpu_reset() at its one-to-one mapped
address.
I've tested on KZM (arm v6) and Beagleboard (omap)
---
arch/arm/kernel/machine_kexec.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
Index: linux-2.6/arch/arm/kernel/machine_kexec.c
===================================================================
--- linux-2.6.orig/arch/arm/kernel/machine_kexec.c 2011-12-04 21:11:53.280725573 +1100
+++ linux-2.6/arch/arm/kernel/machine_kexec.c 2011-12-14 14:37:08.227654151 +1100
@@ -120,5 +120,13 @@ void machine_kexec(struct kimage *image)
cpu_proc_fin();
outer_inv_all();
flush_cache_all();
- cpu_reset(reboot_code_buffer_phys);
+ /*
+ * cpu_reset disables the MMU, so branch to its (1-to-1 mapped)
+ * physical address not its virtual one.
+ */
+ {
+ void (*cpu_reset_phys)(unsigned long dest) =
+ virt_to_phys(cpu_reset);
+ cpu_reset_phys(reboot_code_buffer_phys);
+ }
}
--
Dr Peter Chubb http://www.gelato.unsw.edu.au peterc AT gelato.unsw.edu.au
http://www.ertos.nicta.com.au ERTOS within National ICT Australia
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists