From patchwork Sat May 13 22:04:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kirill A. Shutemov" X-Patchwork-Id: 93616 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp5993142vqo; Sat, 13 May 2023 15:15:50 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7tUbmKrTdqOzb28zAN71YKrMkTZIUUNlmJkgqngIJjdiyvs+bVy4yqDaJUcrBHFSiWr5zU X-Received: by 2002:a17:902:ec8c:b0:1a9:80a0:47ef with SMTP id x12-20020a170902ec8c00b001a980a047efmr42678419plg.20.1684016150158; Sat, 13 May 2023 15:15:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1684016150; cv=none; d=google.com; s=arc-20160816; b=TYiX5qEfyCpWOd41zflogvvHXa7D4e4KhrZjt1XvTTjbq+RoFD1OL/B8d5iRv5ipS7 Br1kOqORII5hNek20JizGzOMmifXSH37kghGkTsgA7wwl7QPgedSZa47QnbuGShbR9aI Ki2l3Q0yDydjPto12J8L7QuDmB80oXXesVOsfptiU5BpyaxsfmQj4KWS8wau1ZqSmTvQ 7q70EVln0YpA9s9QrDRkaWp4HUnH7UBMUhvJvakwVpjODqmm0CZ7eEterjlw/K0LlXJt 34l5YSreF+OvTkPFXC15ssXQiqo/WvH9CktEUYiP8U69pv//RNpyBT/YwRljrXNAxGeo ncRw== 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=ZC1H+SVlO53smocewfMX3MBnMZTnTOy5PrIz8NwD1ek=; b=a9Rwqz9dOBXLLI6ZOmZq2lvXkjQmMhq9yd34KEYWu8MFJO/76jF+Awk+NvJ+2PkCzV hZ/hB/sNdb4IYnQTd2X80ba7vAMyNWU5cANh3GRPjccho1YUN/l+5MQqGE/VaQXuTVxA tAeb/JmpLiaIqwlOpyZacFE0rhD4LzpHQmlvrlGK2sk//cQNAKEY6bkvDYJLGGahMMog yB67257589n4IcP/qVJPPRubyPvcIShX2gm/D8lcI3JhjU0XPRl1uNVUn8KcjBRhpPUe nka5zsEVuusk20Zikcn40/yvER1Cph5K2nmsiK6x76xoM/958Ss5/7LXvSAH9AI9+wV4 tuEg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b="F/VkRRJ4"; 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=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 12-20020a17090a000c00b0025021842c2bsi21404255pja.185.2023.05.13.15.15.35; Sat, 13 May 2023 15:15:50 -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=@intel.com header.s=Intel header.b="F/VkRRJ4"; 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=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231646AbjEMWEx (ORCPT + 99 others); Sat, 13 May 2023 18:04:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230369AbjEMWEq (ORCPT ); Sat, 13 May 2023 18:04:46 -0400 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F68830E7; Sat, 13 May 2023 15:04:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1684015485; x=1715551485; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=74C6EjHk9vtTut2nxMktdKwMlSXxa+Ikleh1JSyXolE=; b=F/VkRRJ4Pvq9ReMU5ao2Y6fR2j6BxhauN2iVW7Z5Tuy2H9RS2MPBe5cX 7znmlgWYD7ds3VcRaZZGipnLCokVPyiUmy08ReI4bqt61TMliXW8YK8Gy lhfGxIlQasD+jLWXwVgZlF1yvyMPo+D6jOkjDGuR9XtyDNnTHrGYLaVXy JJuLFC4WdnWtKsFbxoek/s3Jo2+QcoaFM0djiL/kGUUlrGDHK0f+rF26x TTpMhAsb4+kzUMS+74711c65lh3n2b0mqpkQaWI2lUkIT7l4EjQc8aGoc QIO3LRD9eX9InvO2mPhZGsxt+p3RLkrWhS2xtlrNkgxTwQV+c7B5XQEDw Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10709"; a="379142515" X-IronPort-AV: E=Sophos;i="5.99,273,1677571200"; d="scan'208";a="379142515" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 May 2023 15:04:44 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10709"; a="733429545" X-IronPort-AV: E=Sophos;i="5.99,273,1677571200"; d="scan'208";a="733429545" Received: from sorinaau-mobl1.ger.corp.intel.com (HELO box.shutemov.name) ([10.252.62.145]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 May 2023 15:04:36 -0700 Received: by box.shutemov.name (Postfix, from userid 1000) id 051AE10CF7A; Sun, 14 May 2023 01:04:34 +0300 (+03) From: "Kirill A. Shutemov" To: Borislav Petkov , Andy Lutomirski , Dave Hansen , Sean Christopherson , Andrew Morton , Joerg Roedel , Ard Biesheuvel Cc: Andi Kleen , Kuppuswamy Sathyanarayanan , David Rientjes , Vlastimil Babka , Tom Lendacky , Thomas Gleixner , Peter Zijlstra , Paolo Bonzini , Ingo Molnar , Dario Faggioli , Mike Rapoport , David Hildenbrand , Mel Gorman , marcelo.cerri@canonical.com, tim.gardner@canonical.com, khalid.elmously@canonical.com, philip.cox@canonical.com, aarcange@redhat.com, peterx@redhat.com, x86@kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, "Kirill A. Shutemov" Subject: [PATCHv11 4/9] x86/boot/compressed: Handle unaccepted memory Date: Sun, 14 May 2023 01:04:13 +0300 Message-Id: <20230513220418.19357-5-kirill.shutemov@linux.intel.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20230513220418.19357-1-kirill.shutemov@linux.intel.com> References: <20230513220418.19357-1-kirill.shutemov@linux.intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE, T_SCC_BODY_TEXT_LINE,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?1765818918736721441?= X-GMAIL-MSGID: =?utf-8?q?1765818918736721441?= The firmware will pre-accept the memory used to run the stub. But, the stub is responsible for accepting the memory into which it decompresses the main kernel. Accept memory just before decompression starts. The stub is also responsible for choosing a physical address in which to place the decompressed kernel image. The KASLR mechanism will randomize this physical address. Since the unaccepted memory region is relatively small, KASLR would be quite ineffective if it only used the pre-accepted area (EFI_CONVENTIONAL_MEMORY). Ensure that KASLR randomizes among the entire physical address space by also including EFI_UNACCEPTED_MEMORY. Signed-off-by: Kirill A. Shutemov Reviewed-by: Liam Merwick Reviewed-by: Tom Lendacky --- arch/x86/boot/compressed/efi.h | 1 + arch/x86/boot/compressed/kaslr.c | 35 +++++++++++++++++++++----------- arch/x86/boot/compressed/misc.c | 6 ++++++ arch/x86/boot/compressed/misc.h | 6 ++++++ 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/arch/x86/boot/compressed/efi.h b/arch/x86/boot/compressed/efi.h index 7db2f41b54cd..cf475243b6d5 100644 --- a/arch/x86/boot/compressed/efi.h +++ b/arch/x86/boot/compressed/efi.h @@ -32,6 +32,7 @@ typedef struct { } efi_table_hdr_t; #define EFI_CONVENTIONAL_MEMORY 7 +#define EFI_UNACCEPTED_MEMORY 15 #define EFI_MEMORY_MORE_RELIABLE \ ((u64)0x0000000000010000ULL) /* higher reliability */ diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index 454757fbdfe5..749f0fe7e446 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -672,6 +672,28 @@ static bool process_mem_region(struct mem_vector *region, } #ifdef CONFIG_EFI + +/* + * Only EFI_CONVENTIONAL_MEMORY and EFI_UNACCEPTED_MEMORY (if supported) are + * guaranteed to be free. + * + * It is more conservative in picking free memory than the EFI spec allows: + * + * According to the spec, EFI_BOOT_SERVICES_{CODE|DATA} are also free memory + * and thus available to place the kernel image into, but in practice there's + * firmware where using that memory leads to crashes. + */ +static inline bool memory_type_is_free(efi_memory_desc_t *md) +{ + if (md->type == EFI_CONVENTIONAL_MEMORY) + return true; + + if (md->type == EFI_UNACCEPTED_MEMORY) + return IS_ENABLED(CONFIG_UNACCEPTED_MEMORY); + + return false; +} + /* * Returns true if we processed the EFI memmap, which we prefer over the E820 * table if it is available. @@ -716,18 +738,7 @@ process_efi_entries(unsigned long minimum, unsigned long image_size) for (i = 0; i < nr_desc; i++) { md = efi_early_memdesc_ptr(pmap, e->efi_memdesc_size, i); - /* - * Here we are more conservative in picking free memory than - * the EFI spec allows: - * - * According to the spec, EFI_BOOT_SERVICES_{CODE|DATA} are also - * free memory and thus available to place the kernel image into, - * but in practice there's firmware where using that memory leads - * to crashes. - * - * Only EFI_CONVENTIONAL_MEMORY is guaranteed to be free. - */ - if (md->type != EFI_CONVENTIONAL_MEMORY) + if (!memory_type_is_free(md)) continue; if (efi_soft_reserve_enabled() && diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 014ff222bf4b..eb8df0d4ad51 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -455,6 +455,12 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, #endif debug_putstr("\nDecompressing Linux... "); + + if (IS_ENABLED(CONFIG_UNACCEPTED_MEMORY)) { + debug_putstr("Accepting memory... "); + accept_memory(__pa(output), __pa(output) + needed_size); + } + __decompress(input_data, input_len, NULL, NULL, output, output_len, NULL, error); entry_offset = parse_elf(output); diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index 2f155a0e3041..9663d1839f54 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -247,4 +247,10 @@ static inline unsigned long efi_find_vendor_table(struct boot_params *bp, } #endif /* CONFIG_EFI */ +#ifdef CONFIG_UNACCEPTED_MEMORY +void accept_memory(phys_addr_t start, phys_addr_t end); +#else +static inline void accept_memory(phys_addr_t start, phys_addr_t end) {} +#endif + #endif /* BOOT_COMPRESSED_MISC_H */