Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 487ACC7618D for ; Tue, 14 Mar 2023 10:17:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230162AbjCNKRv (ORCPT ); Tue, 14 Mar 2023 06:17:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40030 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230089AbjCNKRe (ORCPT ); Tue, 14 Mar 2023 06:17:34 -0400 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9C59C9BA74; Tue, 14 Mar 2023 03:16:36 -0700 (PDT) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id 4AC7B40770A5; Tue, 14 Mar 2023 10:16:03 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 4AC7B40770A5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1678788963; bh=Ur0w6W+I5f3bUpQ2HkklMI9fjx8VadeZnwDz8ECMaWM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JDGCTIncxqx4ZTcEsbpCGWhvBHr/2Zfoa+QIUZLI7TXyu1AleFs2Av2sC8jhgrCVC 5AGgAAW7Lme9pZX5ZgbCEuqI9WwbvT12gQGnYVuIPfpH7Tcm09fBECdEfEguWbq0x3 /4McGq+kf584r3iHHnYwr+H3ZROA51FbXfYKcx0o= From: Evgeniy Baskov To: Ard Biesheuvel Cc: Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , Gerd Hoffmann , "Limonciello, Mario" , joeyli , lvc-project@linuxtesting.org, x86@kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v5 13/27] x86/boot: Split trampoline and pt init code Date: Tue, 14 Mar 2023 13:13:40 +0300 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When allocating trampoline from libstub trampoline allocation is performed separately, so it needs to be skipped. Split trampoline initialization and allocation code into two functions to make them invokable separately. Tested-by: Mario Limonciello Signed-off-by: Evgeniy Baskov --- arch/x86/boot/compressed/pgtable_64.c | 69 ++++++++++++++++----------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c index c7cf5a1059a8..d71a62b7cf06 100644 --- a/arch/x86/boot/compressed/pgtable_64.c +++ b/arch/x86/boot/compressed/pgtable_64.c @@ -106,12 +106,8 @@ static unsigned long find_trampoline_placement(void) return bios_start - TRAMPOLINE_32BIT_SIZE; } -struct paging_config paging_prepare(void *rmode) +bool trampoline_pgtable_init(struct boot_params *boot_params) { - struct paging_config paging_config = {}; - - /* Initialize boot_params. Required for cmdline_find_option_bool(). */ - boot_params = rmode; /* * Check if LA57 is desired and supported. @@ -125,26 +121,10 @@ struct paging_config paging_prepare(void *rmode) * * That's substitute for boot_cpu_has() in early boot code. */ - if (IS_ENABLED(CONFIG_X86_5LEVEL) && - !cmdline_find_option_bool("no5lvl") && - native_cpuid_eax(0) >= 7 && - (native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31)))) { - paging_config.l5_required = 1; - } - - paging_config.trampoline_start = find_trampoline_placement(); - - trampoline_32bit = (unsigned long *)paging_config.trampoline_start; - - /* Preserve trampoline memory */ - memcpy(trampoline_save, trampoline_32bit, TRAMPOLINE_32BIT_SIZE); - - /* Clear trampoline memory first */ - memset(trampoline_32bit, 0, TRAMPOLINE_32BIT_SIZE); - - /* Copy trampoline code in place */ - memcpy(trampoline_32bit + TRAMPOLINE_32BIT_CODE_OFFSET / sizeof(unsigned long), - &trampoline_32bit_src, TRAMPOLINE_32BIT_CODE_SIZE); + bool l5_required = IS_ENABLED(CONFIG_X86_5LEVEL) && + !cmdline_find_option_bool("no5lvl") && + native_cpuid_eax(0) >= 7 && + (native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31))); /* * The code below prepares page table in trampoline memory. @@ -160,10 +140,10 @@ struct paging_config paging_prepare(void *rmode) * We are not going to use the page table in trampoline memory if we * are already in the desired paging mode. */ - if (paging_config.l5_required == !!(native_read_cr4() & X86_CR4_LA57)) + if (l5_required == !!(native_read_cr4() & X86_CR4_LA57)) goto out; - if (paging_config.l5_required) { + if (l5_required) { /* * For 4- to 5-level paging transition, set up current CR3 as * the first and the only entry in a new top-level page table. @@ -185,6 +165,41 @@ struct paging_config paging_prepare(void *rmode) (void *)src, PAGE_SIZE); } +out: + return l5_required; +} + +struct paging_config paging_prepare(void *rmode) +{ + struct paging_config paging_config = {}; + + /* Initialize boot_params. Required for cmdline_find_option_bool(). */ + boot_params = rmode; + + /* + * We only need to find trampoline placement, if we have + * not already done it from libstub. + */ + + paging_config.trampoline_start = find_trampoline_placement(); + trampoline_32bit = (unsigned long *)paging_config.trampoline_start; + + /* + * Preserve trampoline memory. When trampoline is located in memory + * owned by us, i.e. allocated in EFISTUB, we don't care about previous + * contents of this memory so copying can also be skipped. + */ + memcpy(trampoline_save, trampoline_32bit, TRAMPOLINE_32BIT_SIZE); + + /* Clear trampoline memory first */ + memset(trampoline_32bit, 0, TRAMPOLINE_32BIT_SIZE); + + /* Copy trampoline code in place */ + memcpy(trampoline_32bit + TRAMPOLINE_32BIT_CODE_OFFSET / sizeof(unsigned long), + &trampoline_32bit_src, TRAMPOLINE_32BIT_CODE_SIZE); + + paging_config.l5_required = trampoline_pgtable_init(boot_params); + out: return paging_config; } -- 2.39.2