From patchwork Fri Jun 2 10:13:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 102466 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp928405vqr; Fri, 2 Jun 2023 03:36:36 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6JSRyObcQScFlfkrhL2q56Al8kfJbvCLKKQ5CcfH4H8hPm9fcDLgqBDoWMss2JamT1/5AM X-Received: by 2002:a05:6a00:23d6:b0:63d:3a18:4a08 with SMTP id g22-20020a056a0023d600b0063d3a184a08mr10101218pfc.24.1685702196546; Fri, 02 Jun 2023 03:36:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685702196; cv=none; d=google.com; s=arc-20160816; b=l3EvylYUBx9t8SkGxnAbQ6x4hHGF7vtGnNLuWBOtyG+1AIxfhDbfJ5vpWPH+l1SzaE 4dVIzVfCODbHlyIF1J6nH9uWhV6h48YSjtSCzYDCytmLak3Vz37dGtWwAOW6239+jfU0 nAY30KiVf+dmARw8aGNdIjVsKcFRUuqYsfxVQaIn7aYZrqM3ZViiaPKnsXdmCSNweGk8 T0FF7kJPOw3l+X73UH8qGse8jv/knuxW/Kv1EP3KvMUBAjdfLkOeaW9E21IYUaymsv/9 lNWoA+Er7jn4UnBhpOtMwm+qroCGwZvN0PQWudvFvHPeACJ0Cki2u2GyFY7icScF0KM5 W8KA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=nEzGCrqtPMvKAlAsmeFYNAjbdU1NAif1Mw7xsg8ylaY=; b=bfHgK2ik4utNqrsE8ezyJv1K0AiPNMHxWqPMa+ifM0pkfQ13jE6WHDGy7TxfS1aXEi OcWP0nQtpvzJpnjpUzB1GD3xUTbrsTHdt3Vkwlz3Kp1TdsdyvjUB1NjN6IAAdnRYxXNw pwS5trjn0ZxBmlkfNtauYKCTbcOy59EPrGNRU4TeXp+jjSfU+8K8RqqBA16UBI9g0T9H 5MHwiC0S1BuK/OE0ZANmA9U/VMl/GIfFH+Fq30CZjiOIxNWvC0O4gafcr7xsZnMbLf8K GKXVNc0HOCXdtcQ7+6TZLakP4LCoap9TJ6iLxskA3y41ch+bHYmtsWk5eWESp5Z5WZD9 P/NQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=NBKBOfWv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id t12-20020aa7946c000000b00652908aedd3si522143pfq.249.2023.06.02.03.36.20; Fri, 02 Jun 2023 03:36:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=NBKBOfWv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235508AbjFBKYq (ORCPT + 99 others); Fri, 2 Jun 2023 06:24:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46468 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235420AbjFBKXs (ORCPT ); Fri, 2 Jun 2023 06:23:48 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F32010EB; Fri, 2 Jun 2023 03:23:18 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 01D2364E63; Fri, 2 Jun 2023 10:23:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 76E3FC433D2; Fri, 2 Jun 2023 10:23:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1685701397; bh=g3nSTumb/KYsp4GqRL0zJ1a7x2cI2HwxP02u+R5/mbI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NBKBOfWv0jG5QaD+uhn1eNfnePlAIv9FspYCYiwSE/yvaw5zGyKDvWW8yYW2na42/ bTVAMTliii6hsUXd6P4tiPR69wJqTkvBYhvAzkJpRf2j2ARIxRg86WzubzBviwg8ws 2JBxVKNT/IfMkDqvbdb04mJVKiem5nKawkp8TXkl+uTnN4++DJbWG1uZqEHm4O5wpR gOKplx6OOltL7RPaTRZmXoO5Z6IU9VI1rwn7cEQrRzuMNR/FUuIOIodG/Aq53nrErF VqrdpHKz0Eh8lOolqeK7CSND6MOvNmhmsMBGGc5DmvSS6RtQEMEbwNY16RKuswjeze ZkBUiKkNQdckw== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , Gerd Hoffmann , Dave Young , Mario Limonciello , Kees Cook , Tom Lendacky , "Kirill A . Shutemov" , Linus Torvalds , Joerg Roedel Subject: [PATCH v4 16/21] x86/decompressor: Move global symbol references to C code Date: Fri, 2 Jun 2023 12:13:08 +0200 Message-Id: <20230602101313.3557775-17-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230602101313.3557775-1-ardb@kernel.org> References: <20230602101313.3557775-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5078; i=ardb@kernel.org; h=from:subject; bh=g3nSTumb/KYsp4GqRL0zJ1a7x2cI2HwxP02u+R5/mbI=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIaXywOaiaX/FNbXq3vm+2fMiODti3b04m93//ps0VaS6T jil1snTUcrCIMbBICumyCIw+++7nacnStU6z5KFmcPKBDKEgYtTACYiGcXI8EyOrTFdqrL5h9PG r9lzXaqOerSuXXDv+rETL4v933KIf2b4HyGVMkdz2YpnYne3/T4vGio+S+hyevjxquY3rRMyElT qOAA= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-Spam-Status: No, score=-4.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767586866429542635?= X-GMAIL-MSGID: =?utf-8?q?1767586866429542635?= It is no longer necessary to be cautious when referring to global variables in the position independent decompressor code, now that it is built using PIE codegen and makes an assertion in the linker script that no GOT entries exist (which would require adjustment for the actual runtime load address of the decompressor binary). This means global variables can be referenced directly from C code, instead of having to pass their runtime addresses into C routines from asm code, which needs to happen at each call site. Do so for the code that will be called directly from the EFI stub after a subsequent patch, and avoid the need to duplicate this logic a third time. Signed-off-by: Ard Biesheuvel --- arch/x86/boot/compressed/head_32.S | 8 -------- arch/x86/boot/compressed/head_64.S | 8 +------- arch/x86/boot/compressed/misc.c | 16 +++++++++------- 3 files changed, 10 insertions(+), 22 deletions(-) diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index 3530465b5b85ccf3..beee858058df4403 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -168,13 +168,7 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) */ /* push arguments for extract_kernel: */ - pushl output_len@GOTOFF(%ebx) /* decompressed length, end of relocs */ pushl %ebp /* output address */ - pushl input_len@GOTOFF(%ebx) /* input_len */ - leal input_data@GOTOFF(%ebx), %eax - pushl %eax /* input_data */ - leal boot_heap@GOTOFF(%ebx), %eax - pushl %eax /* heap area */ pushl %esi /* real mode pointer */ call extract_kernel /* returns kernel entry point in %eax */ addl $24, %esp @@ -202,8 +196,6 @@ SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end) */ .bss .balign 4 -boot_heap: - .fill BOOT_HEAP_SIZE, 1, 0 boot_stack: .fill BOOT_STACK_SIZE, 1, 0 boot_stack_end: diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index b5bd6be035a7b7ec..3074d278c7e665d8 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -493,11 +493,7 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) * Do the extraction, and jump to the new kernel.. */ movq %r15, %rdi /* pass struct boot_params pointer */ - leaq boot_heap(%rip), %rsi /* malloc area for uncompression */ - leaq input_data(%rip), %rdx /* input_data */ - movl input_len(%rip), %ecx /* input_len */ - movq %rbp, %r8 /* output target address */ - movl output_len(%rip), %r9d /* decompressed length, end of relocs */ + movq %rbp, %rsi /* output target address */ call extract_kernel /* returns kernel entry point in %rax */ /* @@ -636,8 +632,6 @@ SYM_DATA_END_LABEL(boot_idt, SYM_L_GLOBAL, boot_idt_end) */ .bss .balign 4 -SYM_DATA_LOCAL(boot_heap, .fill BOOT_HEAP_SIZE, 1, 0) - SYM_DATA_START_LOCAL(boot_stack) .fill BOOT_STACK_SIZE, 1, 0 .balign 16 diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 36535a3753f5d5fa..ad7a2297c9e186df 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -330,6 +330,11 @@ static size_t parse_elf(void *output) return ehdr.e_entry - LOAD_PHYSICAL_ADDR; } +static u8 boot_heap[BOOT_HEAP_SIZE] __aligned(4); + +extern unsigned char input_data[]; +extern unsigned int input_len, output_len; + /* * The compressed kernel image (ZO), has been moved so that its position * is against the end of the buffer used to hold the uncompressed kernel @@ -347,14 +352,11 @@ static size_t parse_elf(void *output) * |-------uncompressed kernel image---------| * */ -asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, - unsigned char *input_data, - unsigned long input_len, - unsigned char *output, - unsigned long output_len) +asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output) { const unsigned long kernel_total_size = VO__end - VO__text; unsigned long virt_addr = LOAD_PHYSICAL_ADDR; + memptr heap = (memptr)boot_heap; unsigned long needed_size; size_t entry_offset; @@ -412,7 +414,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, * entries. This ensures the full mapped area is usable RAM * and doesn't include any reserved areas. */ - needed_size = max(output_len, kernel_total_size); + needed_size = max((unsigned long)output_len, kernel_total_size); #ifdef CONFIG_X86_64 needed_size = ALIGN(needed_size, MIN_KERNEL_ALIGN); #endif @@ -443,7 +445,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, #ifdef CONFIG_X86_64 if (heap > 0x3fffffffffffUL) error("Destination address too large"); - if (virt_addr + max(output_len, kernel_total_size) > KERNEL_IMAGE_SIZE) + if (virt_addr + needed_size > KERNEL_IMAGE_SIZE) error("Destination virtual address is beyond the kernel mapping area"); #else if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))