From patchwork Mon Apr 13 16:21:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 206420 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8DED6C2BA2B for ; Mon, 13 Apr 2020 16:21:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6540320735 for ; Mon, 13 Apr 2020 16:21:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1586794909; bh=9NQ8R9DhZRgLAt9e4VrhoWte1yWObtKJdqxMgjCyQ3c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=N7B55OpGpxiqp5yoThYi4OyDQ+o7xzjOb3BmnNoLec4ZJDDv8b5Yuh3P80LOo8SeX GmQc/ormXagA3ETmSW/mX3LiPzWOdwxPOXmfxysdtHBC9jpEFNJE8lZgnqAWI/6N8o k7FNVwrSKts5q0J2+LHndO7G0T9LzGBIEwWt8R/A= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731467AbgDMQVt (ORCPT ); Mon, 13 Apr 2020 12:21:49 -0400 Received: from mail.kernel.org ([198.145.29.99]:48752 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731410AbgDMQVs (ORCPT ); Mon, 13 Apr 2020 12:21:48 -0400 Received: from e123331-lin.home (amontpellier-657-1-18-247.w109-210.abo.wanadoo.fr [109.210.65.247]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id D45682072C; Mon, 13 Apr 2020 16:21:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1586794908; bh=9NQ8R9DhZRgLAt9e4VrhoWte1yWObtKJdqxMgjCyQ3c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1WrtGANA8+fBvK2lVHif5A62z+LHP30GAL84+ZMb9NidXr18tuHh6zQknlcrY+ut+ BYIwvdQ0YnvrfzHf9QEWwTsSc9nFd2O9YzIrYzNJWvBnZchG4x6Fb/cYYgRcP3tRLD T/fV8Tl1jhipRBN8wFpNaK3R1rfOCHWVIZRcYbZk= From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, Ard Biesheuvel , Geert Uytterhoeven , Nicolas Pitre , Linus Walleij , Russell King Subject: [PATCH v2 1/5] ARM: decompressor: move headroom variable out of LC0 Date: Mon, 13 Apr 2020 18:21:31 +0200 Message-Id: <20200413162135.14955-2-ardb@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200413162135.14955-1-ardb@kernel.org> References: <20200413162135.14955-1-ardb@kernel.org> Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Before breaking up LC0 into different pieces, move out the variable that is already place-relative (given that it subtracts 'restart' in the expression) and so its value does not need to be added to the runtime address of the LC0 symbol itself. Reviewed-by: Geert Uytterhoeven Signed-off-by: Ard Biesheuvel --- arch/arm/boot/compressed/head.S | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 2d2a42865b39..bb674febf640 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -339,7 +339,7 @@ not_angel: */ mov r0, pc cmp r0, r4 - ldrcc r0, LC0+28 + ldrcc r0, .Lheadroom addcc r0, r0, pc cmpcc r4, r0 orrcc r4, r4, #1 @ remember we skipped cache_on @@ -716,9 +716,11 @@ LC0: .word LC0 @ r1 .word _got_start @ r11 .word _got_end @ ip .word .L_user_stack_end @ sp - .word _end - restart + 16384 + 1024*1024 .size LC0, . - LC0 +.Lheadroom: + .word _end - restart + 16384 + 1024*1024 + .Linflated_image_size_offset: .long (input_data_end - 4) - . From patchwork Mon Apr 13 16:21:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 206419 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 38902C352B6 for ; Mon, 13 Apr 2020 16:21:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 18F972072C for ; Mon, 13 Apr 2020 16:21:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1586794913; bh=Dha10g8oPUJP+G/98rZMUnPkksDJ6YaGlaXB7AkGC4I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=ycAgvUMKbuCo8Pv84Sp9Azx831Ix/hswAdbnbr+FdbKWKktBcU3dyG8LH4FMhLIBX byaDxaQVzt9O++wq3o1D83UDq+74+Gt+oQT4iTuxw81U1EqiGZ+KBDp7es0TDLvpNK pNvkqCK2GlrhTqgOODzVB7ItI4bXFk0/mrsscpDw= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731469AbgDMQVw (ORCPT ); Mon, 13 Apr 2020 12:21:52 -0400 Received: from mail.kernel.org ([198.145.29.99]:48876 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731410AbgDMQVw (ORCPT ); Mon, 13 Apr 2020 12:21:52 -0400 Received: from e123331-lin.home (amontpellier-657-1-18-247.w109-210.abo.wanadoo.fr [109.210.65.247]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 823FC2074B; Mon, 13 Apr 2020 16:21:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1586794911; bh=Dha10g8oPUJP+G/98rZMUnPkksDJ6YaGlaXB7AkGC4I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iIymU/SNXZ4D5k9/7Z2C98y7snNyAJ98AhVfMu6+lCfLHuKnzm7R34jrUTlNg7Egk ymx7pqhuzGrZzuCzn4ZAeRds3X4zm2KhXDn+PRK5lF0weYWXkhIc3jA5anJAkH9vm/ IEmuDhdWZW0ljWdHucL4HsQ2TyEpVe3KRRFo14OU= From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, Ard Biesheuvel , Geert Uytterhoeven , Nicolas Pitre , Linus Walleij , Russell King Subject: [PATCH v2 3/5] ARM: decompressor: defer loading of the contents of the LC0 structure Date: Mon, 13 Apr 2020 18:21:33 +0200 Message-Id: <20200413162135.14955-4-ardb@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200413162135.14955-1-ardb@kernel.org> References: <20200413162135.14955-1-ardb@kernel.org> Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org The remaining contents of LC0 are only used after the point in the decompressor startup code where we enter via 'wont_overwrite'. So move the loading of the LC0 structure after it. This will allow us to jump to wont_overwrite directly from the EFI stub, and execute the decompressor in place at the offset it was loaded by the UEFI firmware. Reviewed-by: Geert Uytterhoeven Signed-off-by: Ard Biesheuvel --- arch/arm/boot/compressed/head.S | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 449457d00c4e..9dea394b286b 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -349,10 +349,6 @@ restart: adr r0, LC1 add sp, sp, r0 add r6, r6, r0 - adr r0, LC0 - ldmia r0, {r1, r2, r3, r11, r12} - sub r0, r0, r1 @ calculate the delta offset - get_inflated_image_size r9, r10, lr #ifndef CONFIG_ZBOOT_ROM @@ -370,9 +366,6 @@ restart: adr r0, LC1 mov r5, #0 @ init dtb size to 0 #ifdef CONFIG_ARM_APPENDED_DTB /* - * r0 = delta - * r2 = BSS start - * r3 = BSS end * r4 = final kernel address (possibly with LSB set) * r5 = appended dtb size (still unknown) * r6 = _edata @@ -380,8 +373,6 @@ restart: adr r0, LC1 * r8 = atags/device tree pointer * r9 = size of decompressed image * r10 = end of this image, including bss/stack/malloc space if non XIP - * r11 = GOT start - * r12 = GOT end * sp = stack pointer * * if there are device trees (dtb) appended to zImage, advance r10 so that the @@ -429,7 +420,6 @@ restart: adr r0, LC1 /* temporarily relocate the stack past the DTB work space */ add sp, sp, r5 - stmfd sp!, {r0-r3, ip, lr} mov r0, r8 mov r1, r6 mov r2, r5 @@ -448,7 +438,6 @@ restart: adr r0, LC1 mov r2, r5 bleq atags_to_fdt - ldmfd sp!, {r0-r3, ip, lr} sub sp, sp, r5 #endif @@ -585,6 +574,10 @@ dtb_check_done: mov pc, r0 wont_overwrite: + adr r0, LC0 + ldmia r0, {r1, r2, r3, r11, r12} + sub r0, r0, r1 @ calculate the delta offset + /* * If delta is zero, we are running at the address we were linked at. * r0 = delta From patchwork Mon Apr 13 16:21:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 206418 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6C1B0C2BA19 for ; Mon, 13 Apr 2020 16:21:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4A79220732 for ; Mon, 13 Apr 2020 16:21:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1586794917; bh=yaoIwi+Ux7uaWMr1LOXjqVIdnt6J1WFg3Howl+bvQKc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=IB2pjUbjCooxmF5IEUVAO0lA4b4X5u+GESYeQ0KJPG/vi39qzDfxLZq1Canv2Q8Cw 92q6l6gsLthBBs1sLypfJnGuVIRQjeNmby0nBQnjNQaWrQdyEJOzq4s/GK2mt4t/ZX ZkKyFbYGU8LgoB8lhHhvTPhw0gF28wNBQURGBpxk= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731471AbgDMQV5 (ORCPT ); Mon, 13 Apr 2020 12:21:57 -0400 Received: from mail.kernel.org ([198.145.29.99]:49018 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731410AbgDMQV4 (ORCPT ); Mon, 13 Apr 2020 12:21:56 -0400 Received: from e123331-lin.home (amontpellier-657-1-18-247.w109-210.abo.wanadoo.fr [109.210.65.247]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 2B10D20678; Mon, 13 Apr 2020 16:21:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1586794915; bh=yaoIwi+Ux7uaWMr1LOXjqVIdnt6J1WFg3Howl+bvQKc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CeB0Zi5AqGuX9YBhTOBuuFfSwB4ikdJolQ1jYDXvWM1bQppsbG2S5eilR6ZOt92u4 h7bk01YAAnDRag7JeYZVScThn5vKv+lsJ4hrAk8sqCTQp33eDixYyUSr7Bko85MM25 Mq0ajwOSBza1MIy77OqfkKEEIEdyjmbhjxCS9ADM= From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, Ard Biesheuvel , Geert Uytterhoeven , Nicolas Pitre , Linus Walleij , Russell King Subject: [PATCH v2 5/5] ARM: decompressor: run decompressor in place if loaded via UEFI Date: Mon, 13 Apr 2020 18:21:35 +0200 Message-Id: <20200413162135.14955-6-ardb@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200413162135.14955-1-ardb@kernel.org> References: <20200413162135.14955-1-ardb@kernel.org> Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org The decompressor can load from anywhere in memory, and the only reason the EFI stub code relocates it is to ensure it appears within the first 128 MiB of memory, so that the uncompressed kernel ends up at the right offset in memory. We can short circuit this, and simply jump into the decompressor startup code at the point where it knows where the base of memory lives. This also means there is no need to disable the MMU and caches, create new page tables and re-enable them. Signed-off-by: Ard Biesheuvel --- arch/arm/boot/compressed/head.S | 37 +++++----------- drivers/firmware/efi/libstub/arm32-stub.c | 45 +++----------------- 2 files changed, 17 insertions(+), 65 deletions(-) diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 9dea394b286b..4ec07c98f9b1 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -1480,37 +1480,22 @@ reloc_code_end: #ifdef CONFIG_EFI_STUB ENTRY(efi_enter_kernel) - mov r7, r0 @ preserve image base - mov r4, r1 @ preserve DT pointer + mov r4, r0 @ preserve image base + mov r8, r1 @ preserve DT pointer - mov r0, r4 @ DT start - add r1, r4, r2 @ DT end + mov r0, r8 @ DT start + add r1, r8, r2 @ DT end bl cache_clean_flush - mov r0, r7 @ relocated zImage - ldr r1, =_edata @ size of zImage - add r1, r1, r0 @ end of zImage - bl cache_clean_flush - - @ The PE/COFF loader might not have cleaned the code we are - @ running beyond the PoU, and so calling cache_off below from - @ inside the PE/COFF loader allocated region is unsafe unless - @ we explicitly clean it to the PoC. - adr r0, call_cache_fn @ region of code we will - adr r1, 0f @ run with MMU off - bl cache_clean_flush - bl cache_off + adr r0, 0f @ switch to our stack + ldr sp, [r0] + add sp, sp, r0 - @ Set parameters for booting zImage according to boot protocol - @ put FDT address in r2, it was returned by efi_entry() - @ r1 is the machine type, and r0 needs to be 0 - mov r0, #0 - mov r1, #0xFFFFFFFF - mov r2, r4 - add r7, r7, #(__efi_start - start) - mov pc, r7 @ no mode switch + mov r5, #0 @ appended DTB size + mov r7, #0xFFFFFFFF @ machine ID + b wont_overwrite ENDPROC(efi_enter_kernel) -0: +0: .long .L_user_stack_end - . #endif .align diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c index 7826553af2ba..0050d811bf20 100644 --- a/drivers/firmware/efi/libstub/arm32-stub.c +++ b/drivers/firmware/efi/libstub/arm32-stub.c @@ -199,14 +199,8 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, unsigned long kernel_base; efi_status_t status; - /* - * Verify that the DRAM base address is compatible with the ARM - * boot protocol, which determines the base of DRAM by masking - * off the low 27 bits of the address at which the zImage is - * loaded. These assumptions are made by the decompressor, - * before any memory map is available. - */ - kernel_base = round_up(dram_base, SZ_128M); + /* use a 16 MiB aligned base for the decompressed kernel */ + kernel_base = round_up(dram_base, SZ_16M) + TEXT_OFFSET; /* * Note that some platforms (notably, the Raspberry Pi 2) put @@ -215,41 +209,14 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, * base of the kernel image is only partially used at the moment. * (Up to 5 pages are used for the swapper page tables) */ - kernel_base += TEXT_OFFSET - 5 * PAGE_SIZE; - - status = reserve_kernel_base(kernel_base, reserve_addr, reserve_size); + status = reserve_kernel_base(kernel_base - 5 * PAGE_SIZE, reserve_addr, + reserve_size); if (status != EFI_SUCCESS) { pr_efi_err("Unable to allocate memory for uncompressed kernel.\n"); return status; } - /* - * Relocate the zImage, so that it appears in the lowest 128 MB - * memory window. - */ - *image_addr = (unsigned long)image->image_base; - *image_size = image->image_size; - status = efi_relocate_kernel(image_addr, *image_size, *image_size, - kernel_base + MAX_UNCOMP_KERNEL_SIZE, 0, 0); - if (status != EFI_SUCCESS) { - pr_efi_err("Failed to relocate kernel.\n"); - efi_free(*reserve_size, *reserve_addr); - *reserve_size = 0; - return status; - } - - /* - * Check to see if we were able to allocate memory low enough - * in memory. The kernel determines the base of DRAM from the - * address at which the zImage is loaded. - */ - if (*image_addr + *image_size > dram_base + ZIMAGE_OFFSET_LIMIT) { - pr_efi_err("Failed to relocate kernel, no low memory available.\n"); - efi_free(*reserve_size, *reserve_addr); - *reserve_size = 0; - efi_free(*image_size, *image_addr); - *image_size = 0; - return EFI_LOAD_ERROR; - } + *image_addr = kernel_base; + *image_size = 0; return EFI_SUCCESS; }