From patchwork Thu Apr 28 22:50:18 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Pitre X-Patchwork-Id: 1223 Return-Path: Delivered-To: unknown Received: from imap.gmail.com (74.125.159.109) by localhost6.localdomain6 with IMAP4-SSL; 08 Jun 2011 14:50:21 -0000 Delivered-To: patches@linaro.org Received: by 10.224.2.73 with SMTP id 9cs165919qai; Thu, 28 Apr 2011 15:50:50 -0700 (PDT) Received: by 10.52.184.98 with SMTP id et2mr447462vdc.285.1304031049222; Thu, 28 Apr 2011 15:50:49 -0700 (PDT) Received: from relais.videotron.ca (relais.videotron.ca [24.201.245.36]) by mx.google.com with ESMTP id e8si3612947vby.53.2011.04.28.15.50.49; Thu, 28 Apr 2011 15:50:49 -0700 (PDT) Received-SPF: neutral (google.com: 24.201.245.36 is neither permitted nor denied by best guess record for domain of nico@fluxnic.net) client-ip=24.201.245.36; Authentication-Results: mx.google.com; spf=neutral (google.com: 24.201.245.36 is neither permitted nor denied by best guess record for domain of nico@fluxnic.net) smtp.mail=nico@fluxnic.net Content-transfer-encoding: 7BIT Received: from xanadu.home ([66.130.28.92]) by VL-MR-MRZ22.ip.videotron.ca (Sun Java(tm) System Messaging Server 6.3-8.01 (built Dec 16 2008; 32bit)) with ESMTP id <0LKD00G7HWSMR9A0@VL-MR-MRZ22.ip.videotron.ca> for patches@linaro.org; Thu, 28 Apr 2011 18:50:47 -0400 (EDT) From: Nicolas Pitre To: Russell King - ARM Linux Cc: linux-arm-kernel@lists.infradead.org, Tony Lindgren , patches@linaro.org Subject: [PATCH 3/9] ARM: zImage: make sure not to relocate on top of the relocation code Date: Thu, 28 Apr 2011 18:50:18 -0400 Message-id: <1304031024-5121-4-git-send-email-nico@fluxnic.net> X-Mailer: git-send-email 1.7.4 In-reply-to: <1304031024-5121-1-git-send-email-nico@fluxnic.net> References: <1304031024-5121-1-git-send-email-nico@fluxnic.net> From: Nicolas Pitre If the zImage load address is slightly below the relocation address, there is a risk for the copied data to overwrite the copy loop or cache flush code that the relocation process requires. Always bump the relocation address by the size of that code to avoid this issue. Noticed by Tony Lindgren . While at it, let's start the copy from the restart symbol which makes the above code size computation possible by the assembler directly, given that we don't need to preserve the code before that point anyway. And therefore we don't need to carry the _start pointer in r5 anymore. Signed-off-by: Nicolas Pitre Tested-by: Tony Lindgren --- arch/arm/boot/compressed/head.S | 25 +++++++++++++++---------- 1 files changed, 15 insertions(+), 10 deletions(-) diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 55a5bcb..6dae179 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -187,15 +187,14 @@ not_angel: bl cache_on restart: adr r0, LC0 - ldmia r0, {r1, r2, r3, r5, r6, r9, r11, r12} - ldr sp, [r0, #32] + ldmia r0, {r1, r2, r3, r6, r9, r11, r12} + ldr sp, [r0, #28] /* * We might be running at a different address. We need * to fix up various pointers. */ sub r0, r0, r1 @ calculate the delta offset - add r5, r5, r0 @ _start add r6, r6, r0 @ _edata #ifndef CONFIG_ZBOOT_ROM @@ -214,31 +213,37 @@ restart: adr r0, LC0 /* * Check to see if we will overwrite ourselves. * r4 = final kernel address - * r5 = start of this image * r9 = size of decompressed image * r10 = end of this image, including bss/stack/malloc space if non XIP * We basically want: * r4 >= r10 -> OK - * r4 + image length <= r5 -> OK + * r4 + image length <= current position (pc) -> OK */ cmp r4, r10 bhs wont_overwrite add r10, r4, r9 - cmp r10, r5 + cmp r10, pc bls wont_overwrite /* * Relocate ourselves past the end of the decompressed kernel. - * r5 = start of this image * r6 = _edata * r10 = end of the decompressed kernel * Because we always copy ahead, we need to do it from the end and go * backward in case the source and destination overlap. */ - /* Round up to next 256-byte boundary. */ - add r10, r10, #256 + /* + * Bump to the next 256-byte boundary with the size of + * the relocation code added. This avoids overwriting + * ourself when the offset is small. + */ + add r10, r10, #((reloc_code_end - restart + 256) & ~255) bic r10, r10, #255 + /* Get start of code we want to copy and align it down. */ + adr r5, restart + bic r5, r5, #31 + sub r9, r6, r5 @ size to copy add r9, r9, #31 @ rounded up to a multiple bic r9, r9, #31 @ ... of 32 bytes @@ -346,7 +351,6 @@ not_relocated: mov r0, #0 LC0: .word LC0 @ r1 .word __bss_start @ r2 .word _end @ r3 - .word _start @ r5 .word _edata @ r6 .word _image_size @ r9 .word _got_start @ r11 @@ -1075,6 +1079,7 @@ memdump: mov r12, r0 #endif .ltorg +reloc_code_end: .align .section ".stack", "aw", %nobits