From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755944Ab1LNECm (ORCPT ); Tue, 13 Dec 2011 23:02:42 -0500 Received: from lemon.ertos.nicta.com.au ([203.143.174.143]:49085 "EHLO lemon.ken.nicta.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753676Ab1LNECk (ORCPT ); Tue, 13 Dec 2011 23:02:40 -0500 Date: Wed, 14 Dec 2011 15:02:10 +1100 Message-ID: From: Peter Chubb To: linux-kernel@vger.kernel.org, linux@arm.linux.org.uk, kexec@lists.infradead.org User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL/10.8 Emacs/23.3 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO) X-Face: GgFg(Z>fx((4\32hvXq<)|jndSniCH~~$D)Ka:P@e@JR1P%Vr}EwUdfwf-4j\rUs#JR{'h# !]])6%Jh~b$VA|ALhnpPiHu[-x~@<"@Iv&|%R)Fq[[,(&Z'O)Q)xCqe1\M[F8#9l8~}#u$S$Rm`S9% \'T@`:&8>Sb*c5d'=eDYI&GF`+t[LfDH="MP5rwOO]w>ALi7'=QJHz&y&C&TE_3j! Organization: National ICT Australia MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII X-SA-Exim-Connect-IP: 2402:1800:4000:2:224:d7ff:feaf:390 X-SA-Exim-Mail-From: peter.chubb@nicta.com.au Subject: [PATCH] Fix kexec reboot on ARM X-SA-Exim-Version: 4.2.1 (built Mon, 22 Mar 2010 06:52:44 +0000) X-SA-Exim-Scanned: Yes (on lemon.ken.nicta.com.au) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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