From patchwork Mon Apr 25 17:15:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Fernandez X-Patchwork-Id: 565902 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 BD8B8C43219 for ; Mon, 25 Apr 2022 17:15:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243821AbiDYRS7 (ORCPT ); Mon, 25 Apr 2022 13:18:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36186 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243749AbiDYRSx (ORCPT ); Mon, 25 Apr 2022 13:18:53 -0400 Received: from mail-oa1-x2e.google.com (mail-oa1-x2e.google.com [IPv6:2001:4860:4864:20::2e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A5FA245A6 for ; Mon, 25 Apr 2022 10:15:48 -0700 (PDT) Received: by mail-oa1-x2e.google.com with SMTP id 586e51a60fabf-e9027efe6aso9450645fac.10 for ; Mon, 25 Apr 2022 10:15:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=eclypsium.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=31fpVwLUvVD/6XAm2dtZJP4qrzc0azCUndly9IICdXE=; b=KnyaefTks6jo+4TILCrF756WGX8lxZt9aHpg0PI9qew7ve2EigS6/YECweUifICg8H LiAgoqO+vwKrnqUqJe60Yhzfl4IRxDCH7Vch0OnSf0MasLEDbaR1qcsK3+9Jpog58ake F4bAxiod+Uu/zhOVRpQ8YJNXcyJMRaQi9/uMpgLuX8oqdN+PudGRnCL9IsfrDWJryraa KQsJD09z4zFNgyowj6+Ncy1TY21huL63RCM/uc8NHQDqRM9DjfJP3RHfBP6TW+I4kd56 5xHxqyMJDOL7qxbQ1IfYpbKFhZUmuZlARjfbywcn3ycXGvjGJWyJkr3Gb2fSI2NqRAGF 8coQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=31fpVwLUvVD/6XAm2dtZJP4qrzc0azCUndly9IICdXE=; b=TfSUnttgAYPMhpXVjc5LUO++XTsrIxiSXb0EklBzPvaUSAIDIlA9gs0BE5vRGl+6Lr /Og/IMDZwoX7O3BgOnTusvU6SwlSXKD+tNlPd/hl8/oN6PXTLsDGpzU4F8UaODS7A1s9 mg5RUBVXhk9z8dYiZpXDxIhaNcRuPGR9x+M2MIoaFRrBoKNxIJYDCbPoxOZjQXnB98e9 xfRPGXcOkHd7EnPhde9jo9Q9cLFDkGwhMnDM05oHXDhmnfibE2hmKMZ8fhh9WhWTy3IL ie+t4BhHGBXRl0pw2E9NuiHk7Ra94STU92/EAjEjEnJFu0QLNiAEB9yQ1M717DFC4kA2 Cvjw== X-Gm-Message-State: AOAM530GZIm1WG0dUt5F5jjsDFLDnoaqbJPBv4VnJSt4/0eOKvStoa64 h262CKKnETATyv7ARrvxW2Z4qQ== X-Google-Smtp-Source: ABdhPJxvV/YHrMeAQmhkW4afxhbyXcn6p7T6NUeeJ6tU6iHC/HNuYfsN2vuiql0DYLtiS3hO/Qmmlw== X-Received: by 2002:a05:6870:3052:b0:da:a150:befe with SMTP id u18-20020a056870305200b000daa150befemr7457503oau.129.1650906947228; Mon, 25 Apr 2022 10:15:47 -0700 (PDT) Received: from localhost ([181.97.174.128]) by smtp.gmail.com with ESMTPSA id q12-20020a4ad54c000000b003245ac0a745sm4538568oos.22.2022.04.25.10.15.41 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 25 Apr 2022 10:15:46 -0700 (PDT) From: Martin Fernandez To: linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-mm@kvack.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, ardb@kernel.org, dvhart@infradead.org, andy@infradead.org, gregkh@linuxfoundation.org, rafael@kernel.org, rppt@kernel.org, akpm@linux-foundation.org, daniel.gutson@eclypsium.com, hughsient@gmail.com, alex.bazhaniuk@eclypsium.com, alison.schofield@intel.com, keescook@chromium.org, Martin Fernandez Subject: [PATCH v7 1/8] mm/memblock: Tag memblocks with crypto capabilities Date: Mon, 25 Apr 2022 14:15:19 -0300 Message-Id: <20220425171526.44925-2-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220425171526.44925-1-martin.fernandez@eclypsium.com> References: <20220425171526.44925-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Add the capability to mark regions of the memory memory_type able of hardware memory encryption. Also add the capability to query if all regions of a memory node are able to do hardware memory encryption to call it when initializing the nodes. Warn the user if a node has both encryptable and non-encryptable regions. Signed-off-by: Martin Fernandez --- include/linux/memblock.h | 5 ++++ mm/memblock.c | 62 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 50ad19662a32..00c4f1a20335 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -40,6 +40,7 @@ extern unsigned long long max_possible_pfn; * via a driver, and never indicated in the firmware-provided memory map as * system RAM. This corresponds to IORESOURCE_SYSRAM_DRIVER_MANAGED in the * kernel resource tree. + * @MEMBLOCK_CRYPTO_CAPABLE: capable of hardware encryption */ enum memblock_flags { MEMBLOCK_NONE = 0x0, /* No special request */ @@ -47,6 +48,7 @@ enum memblock_flags { MEMBLOCK_MIRROR = 0x2, /* mirrored region */ MEMBLOCK_NOMAP = 0x4, /* don't add to kernel direct mapping */ MEMBLOCK_DRIVER_MANAGED = 0x8, /* always detected via a driver */ + MEMBLOCK_CRYPTO_CAPABLE = 0x10, /* capable of hardware encryption */ }; /** @@ -120,6 +122,9 @@ int memblock_physmem_add(phys_addr_t base, phys_addr_t size); void memblock_trim_memory(phys_addr_t align); bool memblock_overlaps_region(struct memblock_type *type, phys_addr_t base, phys_addr_t size); +bool memblock_node_is_crypto_capable(int nid); +int memblock_mark_crypto_capable(phys_addr_t base, phys_addr_t size); +int memblock_clear_crypto_capable(phys_addr_t base, phys_addr_t size); int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size); int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size); int memblock_mark_mirror(phys_addr_t base, phys_addr_t size); diff --git a/mm/memblock.c b/mm/memblock.c index e4f03a6e8e56..fe62f81572e6 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -191,6 +191,40 @@ bool __init_memblock memblock_overlaps_region(struct memblock_type *type, return i < type->cnt; } +/** + * memblock_node_is_crypto_capable - get if whole node is capable + * of encryption + * @nid: number of node + * + * Iterate over all memory memblock_type and find if all regions under + * node @nid are capable of hardware encryption. + * + * Return: + * true if every region in memory memblock_type is capable of + * encryption, false otherwise. + */ +bool __init_memblock memblock_node_is_crypto_capable(int nid) +{ + struct memblock_region *region; + int crypto_capables = 0; + int not_crypto_capables = 0; + + for_each_mem_region(region) { + if (memblock_get_region_node(region) == nid) { + if (region->flags & MEMBLOCK_CRYPTO_CAPABLE) + crypto_capables++; + else + not_crypto_capables++; + } + } + + if (crypto_capables > 0 && not_crypto_capables > 0) + pr_warn("Node %d has %d regions that are encryptable and %d regions that aren't", + nid, not_crypto_capables, crypto_capables); + + return not_crypto_capables == 0; +} + /** * __memblock_find_range_bottom_up - find free area utility in bottom-up * @start: start of candidate range @@ -891,6 +925,34 @@ static int __init_memblock memblock_setclr_flag(phys_addr_t base, return 0; } +/** + * memblock_mark_crypto_capable - Mark memory regions capable of hardware + * encryption with flag MEMBLOCK_CRYPTO_CAPABLE. + * @base: the base phys addr of the region + * @size: the size of the region + * + * Return: 0 on success, -errno on failure. + */ +int __init_memblock memblock_mark_crypto_capable(phys_addr_t base, + phys_addr_t size) +{ + return memblock_setclr_flag(base, size, 1, MEMBLOCK_CRYPTO_CAPABLE); +} + +/** + * memblock_clear_crypto_capable - Clear flag MEMBLOCK_CRYPTO for a + * specified region. + * @base: the base phys addr of the region + * @size: the size of the region + * + * Return: 0 on success, -errno on failure. + */ +int __init_memblock memblock_clear_crypto_capable(phys_addr_t base, + phys_addr_t size) +{ + return memblock_setclr_flag(base, size, 0, MEMBLOCK_CRYPTO_CAPABLE); +} + /** * memblock_mark_hotplug - Mark hotpluggable memory with flag MEMBLOCK_HOTPLUG. * @base: the base phys addr of the region From patchwork Mon Apr 25 17:15:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Fernandez X-Patchwork-Id: 565901 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 11244C433FE for ; Mon, 25 Apr 2022 17:16:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243948AbiDYRTl (ORCPT ); Mon, 25 Apr 2022 13:19:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230461AbiDYRTc (ORCPT ); Mon, 25 Apr 2022 13:19:32 -0400 Received: from mail-oi1-x234.google.com (mail-oi1-x234.google.com [IPv6:2607:f8b0:4864:20::234]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1780627B16 for ; Mon, 25 Apr 2022 10:16:03 -0700 (PDT) Received: by mail-oi1-x234.google.com with SMTP id a10so17820820oif.9 for ; Mon, 25 Apr 2022 10:16:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=eclypsium.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=scNNecAxK89bCsIv0vpIcsFL1bTqr463ACa9Pmhvay4=; b=Xwe/HZQ7QWugCsF4WnCrUGpuXwV1gaK3ZKZdlbT70p+37ejUk3CLqzzzPcu5CNkCLf CGrax6l11PoWQUWAiqepna03GEHKQuPCaABKVFzgk1+QB6dKZPw49cMsm2dI7OipMjGf 4p3gpErYOE85yNl37xI80+X0kBuIv8a27lPKf1GrFBbjhxbzGv6Ff97rQZQLsW4P5MBp 4dhjSTORIXAlRYu7rKmo5mqF78SpA5YnhC42lifS4/WCQAGP8Z0cVIe2jdgK6Ds0IgOv 9U7YRa3Dd0uYubs5wbYMhhiw+1OBoJ0kh1nuJi6TtmpkxTeJ4ecWP8jBdria2LZdCbkW fkMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=scNNecAxK89bCsIv0vpIcsFL1bTqr463ACa9Pmhvay4=; b=6pwIFOEJWAW9TodxAwItPrZ+bssdmDBuRXUWt6tRuPAQ0JgKTaDPXLpn0ox1XLHFm5 gXxSGfWg0UmU6lLeYEOTpOSD7ijjf95WER3If5VYM9c2ycQ/SfG3+YO99evNpCvkI7Jm HVbNSFi8SklYSV3JTZTISUxgdzkdX22t5/mpzJdctZuQ/3mk+SX7MnETb8laql41Ot4R xAzstJVxs+VdZ85Bh2xaJPFkSfM0UKvFSkBPNWWGMc3p7R/z16FGASfFFklh74koH+5N ZaQCrUpJOvkhGvbmTFfqUbPzq1QFoTChI1tPFa+ZvkMQB7Btt4JcovSFhVSTykwAOsQU si8g== X-Gm-Message-State: AOAM531Q8//a6CDtEMi0Czvz7Ku9RaHibG/LhVFlFGCyREPM63ImcWqF gL8EfsYcqasQNPhWcQSsfYr+tA== X-Google-Smtp-Source: ABdhPJxdW0TUVi/qCKY+MEYfc75LBEinyGxemFyKERNQFWQ35/MgZzJ97hAPoKTCadYesjTyi6gU6Q== X-Received: by 2002:aca:bd41:0:b0:2ec:ff42:814f with SMTP id n62-20020acabd41000000b002ecff42814fmr8838220oif.63.1650906961998; Mon, 25 Apr 2022 10:16:01 -0700 (PDT) Received: from localhost ([181.97.174.128]) by smtp.gmail.com with ESMTPSA id 1-20020a05687011c100b000de98359b43sm3502824oav.1.2022.04.25.10.15.56 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 25 Apr 2022 10:16:01 -0700 (PDT) From: Martin Fernandez To: linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-mm@kvack.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, ardb@kernel.org, dvhart@infradead.org, andy@infradead.org, gregkh@linuxfoundation.org, rafael@kernel.org, rppt@kernel.org, akpm@linux-foundation.org, daniel.gutson@eclypsium.com, hughsient@gmail.com, alex.bazhaniuk@eclypsium.com, alison.schofield@intel.com, keescook@chromium.org, Martin Fernandez Subject: [PATCH v7 3/8] x86/e820: Add infrastructure to refactor e820__range_{update,remove} Date: Mon, 25 Apr 2022 14:15:21 -0300 Message-Id: <20220425171526.44925-4-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220425171526.44925-1-martin.fernandez@eclypsium.com> References: <20220425171526.44925-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org __e820__range_update and e820__range_remove had a very similar flow in its implementation with a few lines different from each other, the lines that actually perform the modification over the e820_table. The similiraties were found in the checks for the different cases on how each entry intersects with the given range (if it does at all). These checks were very presice and error prone so it was not a good idea to have them in both places. Since I need to add a third one, similar to this two, in this and the following patches I'll propose a refactor of these functions. In this patch I introduce: - A new type e820_entry_updater that will carry three callbacks, those callbacks will decide WHEN to perform actions over the e820_table and WHAY actions are going to be performed. Note that there is a void pointer "data". This pointer will carry useful information for the callbacks, like the type that we want to update in e820__range_update or if we want to check the type in e820__range_remove. Check it out in the next patches where I do the rework of __e820__range_update and e820__range_remove. - A new function __e820__handle_range_update that has the flow of the original two functions to refactor. Together with e820_entry_updater will perform the desired update on the input table. On version 6 of this patch some people pointed out that this solution was over-complicated. Mike Rapoport suggested a another solution [1]. I took a look at that, and although it is indeed simpler it's more confusing at the same time. I think is manageable to have a single function to update or remove sections of the table (what Mike did), but when I added the functionality to also update the crypto_capable it became really hard to manage. I think that the approach presented in this patch it's complex but is easier to read, to extend and to test. [1] https://git.kernel.org/rppt/h/x86/e820-update-range Signed-off-by: Martin Fernandez --- arch/x86/kernel/e820.c | 148 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index f267205f2d5a..923585ab8377 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -459,6 +459,154 @@ static int __init append_e820_table(struct boot_e820_entry *entries, u32 nr_entr return __append_e820_table(entries, nr_entries); } +/** + * struct e820_entry_updater - Helper type for + * __e820__handle_range_update(). + * @should_update: Return true if @entry needs to be updated, false + * otherwise. + * @update: Apply desired actions to an @entry that is inside the + * range and satisfies @should_update. + * @new: Create new entry in the table with information gathered from + * @original and @data. + * + * Each function corresponds to an action that + * __e820__handle_range_update() does. Callbacks need to cast @data back + * to the corresponding type. + */ +struct e820_entry_updater { + bool (*should_update)(const struct e820_entry *entry, const void *data); + void (*update)(struct e820_entry *entry, const void *data); + void (*new)(struct e820_table *table, u64 new_start, u64 new_size, + const struct e820_entry *original, const void *data); +}; + +/** + * __e820__handle_intersected_range_update() - Helper function for + * __e820__handle_range_update(). + * @table: Target e820_table. + * @start: Start of the range. + * @size: Size of the range. + * @entry: Current entry that __e820__handle_range_update() was + * looking into. + * @updater: updater parameter of __e820__handle_range_update(). + * @data: data parameter of __e820__handle_range_update(). + * + * Helper for __e820__handle_range_update to handle the case where + * neither the entry completely covers the range nor the range + * completely covers the entry. + * + * Return: The updated size. + */ +static u64 __init +__e820__handle_intersected_range_update(struct e820_table *table, + u64 start, + u64 size, + struct e820_entry *entry, + const struct e820_entry_updater *updater, + const void *data) +{ + u64 end; + u64 entry_end = entry->addr + entry->size; + u64 inner_start; + u64 inner_end; + u64 updated_size = 0; + + if (size > (ULLONG_MAX - start)) + size = ULLONG_MAX - start; + + end = start + size; + inner_start = max(start, entry->addr); + inner_end = min(end, entry_end); + + /* Range and entry do intersect and... */ + if (inner_start < inner_end) { + /* Entry is on the left */ + if (entry->addr < inner_start) { + /* Resize current entry */ + entry->size = inner_start - entry->addr; + /* Entry is on the right */ + } else { + /* Resize and move current section */ + entry->addr = inner_end; + entry->size = entry_end - inner_end; + } + /* Create new entry with intersected region */ + updater->new(table, inner_start, inner_end - inner_start, entry, data); + + updated_size += inner_end - inner_start; + } /* Else: [start, end) doesn't cover entry */ + + return updated_size; +} + +/** + * __e820__handle_range_update(): Helper function to update an address + * range in a e820_table + * @table: e820_table that we want to modify. + * @start: Start of the range. + * @size: Size of the range. + * @updater: Callbacks to modify the table. + * @data: Information to modify the table. This must be an struct + * e820_type_*_data. + * + * Update the table @table in [@start, @start + @size) doing the + * actions given in @updater. + * + * Return: The updated size. + */ +static u64 __init +__e820__handle_range_update(struct e820_table *table, + u64 start, + u64 size, + const struct e820_entry_updater *updater, + const void *data) +{ + u64 updated_size = 0; + u64 end; + unsigned int i; + + if (size > (ULLONG_MAX - start)) + size = ULLONG_MAX - start; + + end = start + size; + + for (i = 0; i < table->nr_entries; i++) { + struct e820_entry *entry = &table->entries[i]; + u64 entry_end = entry->addr + entry->size; + + if (updater->should_update(entry, data)) { + /* Range completely covers entry */ + if (entry->addr >= start && entry_end <= end) { + updated_size += entry->size; + updater->update(entry, data); + /* Entry completely covers range */ + } else if (start > entry->addr && end < entry_end) { + /* Resize current entry */ + entry->size = start - entry->addr; + + /* Create new entry with intersection region */ + updater->new(table, start, size, entry, data); + + /* + * Create a new entry for the leftover + * of the current entry + */ + __e820__range_add(table, end, entry_end - end, + entry->type, + entry->crypto_capable); + + updated_size += size; + } else { + updated_size += + __e820__handle_intersected_range_update(table, start, size, + entry, updater, data); + } + } + } + + return updated_size; +} + static u64 __init __e820__range_update(struct e820_table *table, u64 start, u64 size, enum e820_type old_type, enum e820_type new_type) { From patchwork Mon Apr 25 17:15:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Fernandez X-Patchwork-Id: 565900 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 E0EE5C433FE for ; Mon, 25 Apr 2022 17:16:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230461AbiDYRTv (ORCPT ); Mon, 25 Apr 2022 13:19:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40994 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243957AbiDYRTm (ORCPT ); Mon, 25 Apr 2022 13:19:42 -0400 Received: from mail-oa1-x33.google.com (mail-oa1-x33.google.com [IPv6:2001:4860:4864:20::33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A9C92289A9 for ; Mon, 25 Apr 2022 10:16:17 -0700 (PDT) Received: by mail-oa1-x33.google.com with SMTP id 586e51a60fabf-e656032735so15500788fac.0 for ; Mon, 25 Apr 2022 10:16:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=eclypsium.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ft+wZQIdPNos4T3lDuMvy0g55vrLthZNQPyCA6Ri2Oc=; b=aRdrpQIzsB5Rys7TKFmkToLr1c2+7gMgCFOy3LQCThR0i95Wdz60D85WV4oFBu6CP+ NO1HiG+5q4S26R7wLVT3F3xuPjL0NFcMFbGs8ilMjJ+Rnv0GQrkwI3D/uqHL2+HU/NaN pOL8mA1pjelM8jseVenZ/cNtAoiSrf569bi8DQdPzZ7hCdC5MQfL2ZNL+bCrxWN7akup NE0muzOpw0mXDW12dhOGZHESYV77gW+gwQEDEVf0FOExUdFl7nneauWzSDfcATb6bzv8 pbOUFGMAOnCG+imkMSUHMpmO7HHPZBqogf3HMvptmKVewa42f4DvUiHZ3Mz7SvPakHF7 BmtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ft+wZQIdPNos4T3lDuMvy0g55vrLthZNQPyCA6Ri2Oc=; b=sa+DykWqcsjFkzjJTjkuheD4k2MKwEmqwopdYkX8S2r6hFnoLlL2WwWCw6Vnqn1N3a oBRY6myZczcnojMr/DfM+kkVo7bdkdhfjsr5xNs2PMaJcRWJQUT54w/DvVyeJDprEEwy +qR4rVFa68tpSNbNorQsE2V2V8wyQkT2KWwypg9ivfMfo/4trGQTRo8zODu1cTdjzK2V NnWAaEs1UCRlLspbzc+ixnaIC0i8TtHa0pKcFeop6YyjRzPGgdEVihl5BHMS0hma38zO S98mssM7ugmpX9vKDXRAUDBRYA8sttfFZ8vC/al1+Q381RIJncbmQIngiSOriTAPHwTq CNCA== X-Gm-Message-State: AOAM5334Nv6wPDJEg2lrdSkQ8FymCIUKjB61NfBO8BuOOdbfteo/Nfq4 hOA4OTqLI0VjRdxXouGbuycCaw== X-Google-Smtp-Source: ABdhPJxhe3SolTYD/SoMykhNbjVWS3EDWFMCXc59Vp6VJr5Cun6bm5rlf51Rm3y1ZigNDcBZHtq7jw== X-Received: by 2002:a05:6870:63a7:b0:e9:363:51e1 with SMTP id t39-20020a05687063a700b000e9036351e1mr6295289oap.246.1650906976814; Mon, 25 Apr 2022 10:16:16 -0700 (PDT) Received: from localhost ([181.97.174.128]) by smtp.gmail.com with ESMTPSA id ep36-20020a056870a9a400b000de98fe4869sm3651433oab.35.2022.04.25.10.16.11 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 25 Apr 2022 10:16:16 -0700 (PDT) From: Martin Fernandez To: linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-mm@kvack.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, ardb@kernel.org, dvhart@infradead.org, andy@infradead.org, gregkh@linuxfoundation.org, rafael@kernel.org, rppt@kernel.org, akpm@linux-foundation.org, daniel.gutson@eclypsium.com, hughsient@gmail.com, alex.bazhaniuk@eclypsium.com, alison.schofield@intel.com, keescook@chromium.org, Martin Fernandez Subject: [PATCH v7 5/8] x86/e820: Refactor e820__range_remove Date: Mon, 25 Apr 2022 14:15:23 -0300 Message-Id: <20220425171526.44925-6-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220425171526.44925-1-martin.fernandez@eclypsium.com> References: <20220425171526.44925-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Refactor e820__range_remove with the introduction of e820_remover_data, indented to be used as the void pointer in the e820_entry_updater callbacks, and the implementation of the callbacks remove a range in the e820_table. Signed-off-by: Martin Fernandez --- arch/x86/kernel/e820.c | 112 ++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 52 deletions(-) diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 763b8b20a1fd..9e32c9819e99 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -717,66 +717,74 @@ static u64 __init e820__range_update_kexec(u64 start, u64 size, return __e820__range_update(e820_table_kexec, start, size, old_type, new_type); } -/* Remove a range of memory from the E820 table: */ -u64 __init e820__range_remove(u64 start, u64 size, enum e820_type old_type, bool check_type) -{ - int i; - u64 end; - u64 real_removed_size = 0; - - if (size > (ULLONG_MAX - start)) - size = ULLONG_MAX - start; - - end = start + size; - printk(KERN_DEBUG "e820: remove [mem %#010Lx-%#010Lx] ", start, end - 1); - if (check_type) - e820_print_type(old_type); - pr_cont("\n"); - - for (i = 0; i < e820_table->nr_entries; i++) { - struct e820_entry *entry = &e820_table->entries[i]; - u64 final_start, final_end; - u64 entry_end; +/** + * struct e820_remover_data - Helper type for e820__range_remove(). + * @old_type: old_type parameter of e820__range_remove(). + * @check_type: check_type parameter of e820__range_remove(). + * + * This is intended to be used as the @data argument for the + * e820_entry_updater callbacks. + */ +struct e820_remover_data { + enum e820_type old_type; + bool check_type; +}; - if (check_type && entry->type != old_type) - continue; +static bool __init remover__should_update(const struct e820_entry *entry, + const void *data) +{ + const struct e820_remover_data *remover_data = + (const struct e820_remover_data *)data; - entry_end = entry->addr + entry->size; + return !remover_data->check_type || + entry->type == remover_data->old_type; +} - /* Completely covered? */ - if (entry->addr >= start && entry_end <= end) { - real_removed_size += entry->size; - memset(entry, 0, sizeof(*entry)); - continue; - } +static void __init remover__update(struct e820_entry *entry, const void *data) +{ + memset(entry, 0, sizeof(*entry)); +} - /* Is the new range completely covered? */ - if (entry->addr < start && entry_end > end) { - e820__range_add(end, entry_end - end, entry->type); - entry->size = start - entry->addr; - real_removed_size += size; - continue; - } +static void __init remover__new(struct e820_table *table, u64 new_start, + u64 new_size, const struct e820_entry *original, + const void *data) +{ +} - /* Partially covered: */ - final_start = max(start, entry->addr); - final_end = min(end, entry_end); - if (final_start >= final_end) - continue; +/** + * e820__range_remove() - Remove an address range from e820_table. + * @start: Start of the address range. + * @size: Size of the address range. + * @old_type: Type of the entries that we want to remove. + * @check_type: Bool to decide if ignore @old_type or not. + * + * Remove [@start, @start + @size) from e820_table. If @check_type is + * true remove only entries with type @old_type. + * + * Return: The size removed. + */ +u64 __init e820__range_remove(u64 start, u64 size, enum e820_type old_type, + bool check_type) +{ + struct e820_entry_updater updater = { + .should_update = remover__should_update, + .update = remover__update, + .new = remover__new + }; - real_removed_size += final_end - final_start; + struct e820_remover_data data = { + .check_type = check_type, + .old_type = old_type + }; - /* - * Left range could be head or tail, so need to update - * the size first: - */ - entry->size -= final_end - final_start; - if (entry->addr < final_start) - continue; + printk(KERN_DEBUG "e820: remove [mem %#018Lx-%#018Lx] ", start, + start + size - 1); + if (check_type) + e820_print_type(old_type); + pr_cont("\n"); - entry->addr = final_end; - } - return real_removed_size; + return __e820__handle_range_update(e820_table, start, size, &updater, + &data); } void __init e820__update_table_print(void) From patchwork Mon Apr 25 17:15:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Fernandez X-Patchwork-Id: 565899 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 E37E3C43217 for ; Mon, 25 Apr 2022 17:16:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243886AbiDYRUA (ORCPT ); Mon, 25 Apr 2022 13:20:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41426 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243855AbiDYRTp (ORCPT ); Mon, 25 Apr 2022 13:19:45 -0400 Received: from mail-oo1-xc2b.google.com (mail-oo1-xc2b.google.com [IPv6:2607:f8b0:4864:20::c2b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 575D02AE0B for ; Mon, 25 Apr 2022 10:16:31 -0700 (PDT) Received: by mail-oo1-xc2b.google.com with SMTP id j25-20020a4a7519000000b0035e6db06150so580285ooc.6 for ; Mon, 25 Apr 2022 10:16:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=eclypsium.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2VGMhr11GA+eGLRm5CsL28eo528BHkwYTiIF+ncvNsE=; b=hzdDmfKq8Bk9MII6db84BuRQTA/8rrlJsMn81H+8Z6fmZowtvXXor0jrWgoYGoELCw IsIzz074TMbE9AtUH2hfNN9cl4+cL2kALjO15QlLwx+J7IiSpWMDUQXN1ky+b6TyHLgV g8ZcTwU6ddQZlGfTw3ZExEZZIipHXbZS7hfXg/PZIIxAaplsyeLYNZu3Ph7olpJmw70s T5p5+74Sg002Z8SZlFK2U93bEY/7rC/66iOkS3hLBRCcIohkPQmE2rwS/StCBweQD5LG fGpr/YgqwEmPUoDwJp0CpaEWHLvQxyCttWiqadb6WN/2/2KYX9p/eIOXN7IoM+YLhNc3 l0dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2VGMhr11GA+eGLRm5CsL28eo528BHkwYTiIF+ncvNsE=; b=DYXMmaY+5eoikXC6//3YazAy+zs4ERHdaRa6t3Kt6zbHF33kwcMqbfJ14mrkpfmTUK HcjUcWKis8RqtpkMMbPunqMbCCHWiGzwyFLDCH/0FeNc/B2vIljIYdOEHc36/pclSeJd vhNLsVZNJGn54boJdZFDUCp81nIGTTjUTCAaIGN0o7zmnGPCzIb3+IZPwl1E1Ao6MC/4 TwhIPzwEZC/wSIAS0xiMy4Tu22eWH+XaNXemAjHEQBuNz63y6Ps3ODuhGl1OfZsUqsBM vyMBln8kIgbePYb8QtP4mwFJ7FqkgnA6cbEJvfnT68VHBLYLyWzmZC34hvrc8t4me0BA WkzQ== X-Gm-Message-State: AOAM531sipucydBSTkkf1U2/gbeho84hurxsdS74EgcGMoS4VuegCsLQ bbsHY3rjVx2hZgH4D4PgJS2ovg== X-Google-Smtp-Source: ABdhPJw+qg0OrSQnHpLZqEEKRtsnl5QwBjo+IrjHQ4B0lUJPMGV26uBWO99+0KzzBzURpIrWg8ExmQ== X-Received: by 2002:a4a:92d4:0:b0:33a:3d7d:fe5 with SMTP id j20-20020a4a92d4000000b0033a3d7d0fe5mr6747103ooh.83.1650906990628; Mon, 25 Apr 2022 10:16:30 -0700 (PDT) Received: from localhost ([181.97.174.128]) by smtp.gmail.com with ESMTPSA id w8-20020a056830410800b00605b48122eesm1191834ott.14.2022.04.25.10.16.25 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 25 Apr 2022 10:16:30 -0700 (PDT) From: Martin Fernandez To: linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-mm@kvack.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, ardb@kernel.org, dvhart@infradead.org, andy@infradead.org, gregkh@linuxfoundation.org, rafael@kernel.org, rppt@kernel.org, akpm@linux-foundation.org, daniel.gutson@eclypsium.com, hughsient@gmail.com, alex.bazhaniuk@eclypsium.com, alison.schofield@intel.com, keescook@chromium.org, Martin Fernandez Subject: [PATCH v7 7/8] x86/efi: Mark e820_entries as crypto capable from EFI memmap Date: Mon, 25 Apr 2022 14:15:25 -0300 Message-Id: <20220425171526.44925-8-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220425171526.44925-1-martin.fernandez@eclypsium.com> References: <20220425171526.44925-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Add a function to iterate over the EFI Memory Map and mark the regions tagged with EFI_MEMORY_CPU_CRYPTO in the e820_table; and call it from efi_init if add_efi_memmap is disabled. Also modify do_add_efi_memmap to mark the regions there. If add_efi_memmap is false, also check that the e820_table has enough size to (possibly) store also the EFI memmap. Signed-off-by: Martin Fernandez --- arch/x86/platform/efi/efi.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 147c30a81f15..3efa1c620c75 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -184,6 +184,8 @@ static void __init do_add_efi_memmap(void) } e820__range_add(start, size, e820_type); + if (md->attribute & EFI_MEMORY_CPU_CRYPTO) + e820__range_set_crypto_capable(start, size); } e820__update_table(e820_table); } @@ -441,6 +443,34 @@ static int __init efi_config_init(const efi_config_table_type_t *arch_tables) return ret; } +static void __init efi_mark_e820_regions_as_crypto_capable(void) +{ + efi_memory_desc_t *md; + + /* + * Calling e820__range_set_crypto_capable several times + * creates a bunch of entries in the E820 table. They probably + * will get merged when calling update_table but we need the + * space there anyway + */ + if (efi.memmap.nr_map + e820_table->nr_entries >= E820_MAX_ENTRIES) { + pr_err_once("E820 table is not large enough to fit EFI memmap; not marking entries as crypto capable\n"); + return; + } + + for_each_efi_memory_desc(md) { + if (md->attribute & EFI_MEMORY_CPU_CRYPTO) + e820__range_set_crypto_capable(md->phys_addr, + md->num_pages << EFI_PAGE_SHIFT); + } + + /* + * We added and modified regions so it's good to update the + * table to merge/sort + */ + e820__update_table(e820_table); +} + void __init efi_init(void) { if (IS_ENABLED(CONFIG_X86_32) && @@ -494,6 +524,13 @@ void __init efi_init(void) set_bit(EFI_RUNTIME_SERVICES, &efi.flags); efi_clean_memmap(); + /* + * If add_efi_memmap then there is no need to mark the regions + * again + */ + if (!add_efi_memmap) + efi_mark_e820_regions_as_crypto_capable(); + if (efi_enabled(EFI_DBG)) efi_print_memmap(); }