From patchwork Tue Mar 14 10:13:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeniy Baskov X-Patchwork-Id: 69438 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5915:0:0:0:0:0 with SMTP id v21csp1673859wrd; Tue, 14 Mar 2023 03:26:47 -0700 (PDT) X-Google-Smtp-Source: AK7set9Kkm8WO16lnh4zr2FtoEZDVYwDEPVd+iKT9aYLzGsI0inNQvCiN0Sg8UPNB9RLyEUFYBsm X-Received: by 2002:aa7:9483:0:b0:625:7ca9:fb9c with SMTP id z3-20020aa79483000000b006257ca9fb9cmr300038pfk.20.1678789606698; Tue, 14 Mar 2023 03:26:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1678789606; cv=none; d=google.com; s=arc-20160816; b=cfKT2DpiQwdQgYv1DKADMB2u7gODdxl0I+NhmyFPMGs6YJIJHUvxpvCzsUOYaNwr9K uBIvzTJY9ITc3fQ60qO1o62BbU1yyp4Xbh+SDB1G6oTOIOS19FpAe110ML1K6PRI+MFH ClpRSvj8puO1HXYZecCfqzghi6dxw8mkbPyHqg5jrBhimtgUpv+Cp8eNVjQT5SqKqkhA MXCf5V0hRmEdOSFad8EJAVmRM8eEnDdq6lrfCYQdd1XWok/ce00erT1zk4HqlxQkI2Op ARo+YOYNmAckdDP6nVrgAz46esWxSCWmRpcdlz38A9zrg2IHww+HwBbiDOtIaeF/+xWb XqbQ== 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:dkim-filter; bh=Ur0w6W+I5f3bUpQ2HkklMI9fjx8VadeZnwDz8ECMaWM=; b=lDdlkU4N42j+SH+bnBDFOASWv1btbT0FYTRUdxXFnk1O7Bn+LKD1/CsgGjmE4N4oY/ DqMg8vBERkVwMoP1u1J88zOtscZ2t9m17+P8jLXAcdZmtSwFnPfLO67DDp/lIsVXQjS5 7J8nv1zJfCaZSAwbZghzSxW0qVAlw2WHD/NYccUthPs93lqMsbfFN+ef0ZZ67/HfKb4D Co3HSOzDv+iOAwXbyZ89Axjbqpd//ovYakwaCM/BPKwS0XUA0qnKQO03DMynm7Fb5+uN U66a/6lRXaO5wOzEwsORvwnGhEqd8klDYyLfgyU5mMAHTftD6SduuJqOdKuZmJYTr733 aAhQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ispras.ru header.s=default header.b=JDGCTInc; 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=ispras.ru Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y30-20020aa79e1e000000b006257bf333basi292545pfq.65.2023.03.14.03.26.31; Tue, 14 Mar 2023 03:26:46 -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=@ispras.ru header.s=default header.b=JDGCTInc; 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=ispras.ru Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229632AbjCNKRu (ORCPT + 99 others); Tue, 14 Mar 2023 06:17:50 -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 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED 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?1760338490366172251?= X-GMAIL-MSGID: =?utf-8?q?1760338490366172251?= 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; }