From nobody Mon Jun 29 19:43:30 2026 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 AC6D0C43217 for ; Thu, 3 Feb 2022 16:43:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352344AbiBCQn4 (ORCPT ); Thu, 3 Feb 2022 11:43:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60568 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352334AbiBCQnz (ORCPT ); Thu, 3 Feb 2022 11:43:55 -0500 Received: from mail-oo1-xc31.google.com (mail-oo1-xc31.google.com [IPv6:2607:f8b0:4864:20::c31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 11558C06173D for ; Thu, 3 Feb 2022 08:43:55 -0800 (PST) Received: by mail-oo1-xc31.google.com with SMTP id o192-20020a4a2cc9000000b00300af40d795so1941757ooo.13 for ; Thu, 03 Feb 2022 08:43:55 -0800 (PST) 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=zqxGKfIaElLILaxF70bDCH7K86RuUZa6ey16asaAIL8=; b=datlh4dR78ilyTuX5QJMyasJ51wpsY/9yQWHYGQ5q+433ZIPXwWIrpKMsFE6Scjokx VVmwwBvqOxzijJNX6FoIk2lBAXVjwP18b7JWnw/DUTcY2nlfRG1h0DhNZkY/sRr2hBAk cFcAktlfD8CBOQtWCtesgfwtCD30Ag+pnjxeef09PTYlVmecbF7xr47SFmHX4pJr8eaC WbxOL1lARe1FGG//DOrbrVjBmmNl953y/6PcDdyUEevozYmWj3fUpEuOQqaT/kn2Lvke zdywgqZAjdL6sRg3kQs8EKm+q0Gm/wJYCEMcsXnxCnFgDwNUf2wXdDR99WKaXGadra07 jKsg== 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=zqxGKfIaElLILaxF70bDCH7K86RuUZa6ey16asaAIL8=; b=D9S3JZzc/GzUzea/gLaRYpyHamlrOuNkjua8dxlbpCpFkbnEcXS14FZL0jGUaZSUNS TDdWwHqPnoBsFdNuU9v84ub26BurRxDOnXwC+EgvptJ5uo4RHDXoINu9jfMCc68XTSzp LbtaPfkbM74FZv96LsupYQZqLIQ/cXpDyph2XGxlxIrEib1spk+VxZmV7MOVQFs9JBjz cWfQsKGHwZLkRJIhzLBRAhrLrRoLbZITRIQ8Myj8pRvAsvI7LushohhfZ8+TTaJBsntu jy7d34IfoE8u7VZW5+bzjQ2kvawKVr3z8xU/cTMxpSiPFBcF734ya6SJSX5Cb7mBdfyU HX4w== X-Gm-Message-State: AOAM531QrK/yxWTPDAl4RLPBtL3OLMNu/VfDEkgp1Znor4H7xAVrNxcF szNVKGJcH4EiJN+X6WB3aCV6BDXBscWlgdfzhMRSIZaNguFHmNiKnndb+srPAHTfGnB02tA0lRW CA3BbkWBtyl5KL2rer7d3hrrIMecIKJllmF2NchjqPF6/vAMB8wjKorql5SevTmLAUW97neIfr7 GHBQz48smOAuw0y3XV X-Google-Smtp-Source: ABdhPJz3KHjC1PcTs960s+pnZHPdMPi5tX1gUa+Hy63Y3u0iqFld1EfTMFHHJ54cHT2MusHjn7bfpQ== X-Received: by 2002:a05:6870:2144:: with SMTP id g4mr360672oae.30.1643906634240; Thu, 03 Feb 2022 08:43:54 -0800 (PST) Received: from localhost (host8.190-224-49.telecom.net.ar. [190.224.49.8]) by smtp.gmail.com with ESMTPSA id x16sm3107305ooa.6.2022.02.03.08.43.48 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 03 Feb 2022 08:43:54 -0800 (PST) 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 v6 1/6] mm/memblock: Tag memblocks with crypto capabilities Date: Thu, 3 Feb 2022 13:43:23 -0300 Message-Id: <20220203164328.203629-2-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220203164328.203629-1-martin.fernandez@eclypsium.com> References: <20220203164328.203629-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 | 15 ++++++---- mm/memblock.c | 64 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 9dc7cb239d21..73edcce165a5 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -41,13 +41,15 @@ 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 =3D 0x0, /* No special request */ - MEMBLOCK_HOTPLUG =3D 0x1, /* hotpluggable region */ - MEMBLOCK_MIRROR =3D 0x2, /* mirrored region */ - MEMBLOCK_NOMAP =3D 0x4, /* don't add to kernel direct mapping */ - MEMBLOCK_DRIVER_MANAGED =3D 0x8, /* always detected via a driver */ + MEMBLOCK_NONE =3D 0x0, /* No special request */ + MEMBLOCK_HOTPLUG =3D 0x1, /* hotpluggable region */ + MEMBLOCK_MIRROR =3D 0x2, /* mirrored region */ + MEMBLOCK_NOMAP =3D 0x4, /* don't add to kernel direct mapping */ + MEMBLOCK_DRIVER_MANAGED =3D 0x8, /* always detected via a driver */ + MEMBLOCK_CRYPTO_CAPABLE =3D 0x10, /* capable of hardware encryption */ }; =20 /** @@ -121,6 +123,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 1018e50566f3..fcf79befeab3 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -191,6 +191,42 @@ bool __init_memblock memblock_overlaps_region(struct m= emblock_type *type, return i < type->cnt; } =20 +/** + * 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; + bool crypto_capable =3D false; + bool not_crypto_capable =3D false; + + for_each_mem_region(region) { + if (memblock_get_region_node(region) =3D=3D nid) { + crypto_capable =3D + crypto_capable || + (region->flags & MEMBLOCK_CRYPTO_CAPABLE); + not_crypto_capable =3D + not_crypto_capable || + !(region->flags & MEMBLOCK_CRYPTO_CAPABLE); + } + } + + if (crypto_capable && not_crypto_capable) + pr_warn_once("Node %d has regions that are encryptable and regions that = aren't", + nid); + + return !not_crypto_capable; +} + /** * __memblock_find_range_bottom_up - find free area utility in bottom-up * @start: start of candidate range @@ -885,6 +921,34 @@ static int __init_memblock memblock_setclr_flag(phys_a= ddr_t base, return 0; } =20 +/** + * 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_HOT= PLUG. * @base: the base phys addr of the region --=20 2.30.2 From nobody Mon Jun 29 19:43:30 2026 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 862A3C433F5 for ; Thu, 3 Feb 2022 16:44:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352351AbiBCQoH (ORCPT ); Thu, 3 Feb 2022 11:44:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60606 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352354AbiBCQoB (ORCPT ); Thu, 3 Feb 2022 11:44:01 -0500 Received: from mail-vk1-xa2d.google.com (mail-vk1-xa2d.google.com [IPv6:2607:f8b0:4864:20::a2d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D22D3C061401 for ; Thu, 3 Feb 2022 08:44:01 -0800 (PST) Received: by mail-vk1-xa2d.google.com with SMTP id u25so2081398vkk.3 for ; Thu, 03 Feb 2022 08:44:01 -0800 (PST) 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=dL7Kyw5R5uEJ5iFptCvOaKv8TqVxuhvnFOanF/ug8Oo=; b=MR8jXVkyACJhcck+4dcIScEcJjdlILboYDi4bqSv/6PZ8vBTWUY9vgbyWmkv4L/15Q FtimY0idlQDbZUTEV6rjD0xK50eicfInFXj/KAqbBZx+/tiI/11qsBWxJWE2MiAFXpOA /FNHgzWKuvmXWqOkq1muNBj+A2wx5HLtsHpFIY2ndlCa9hIDZgbgMK5TczXwoGmETExB FrOt7tpZowyB0etKJbSK6ojlEgVQ07mYW3A4TZTCmejaIh/8yLC+kSwulqt0/pn+MeM2 ciAwu3tFxEG46MI470mmhgPU7yW2gNwBIIAq3litWGQK53yT6iAypK5CNOL+cpubsYQr 5lpA== 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=dL7Kyw5R5uEJ5iFptCvOaKv8TqVxuhvnFOanF/ug8Oo=; b=QFgRTNawdPW2Z0ZPj6emKdppLXwvLYgHCjzPmbxew+et0CGhznAW7JbEp7SmiKEZvU 1jOGwWBGOpise8chz9IjDxMh54oXo4dkbcXsfk7WdBZotQGGsStJaRUEEJgp5wixOTGB FyxzzbR/FxlCCK1KLlHHyMMoIV6v3VI6X28/9FnCUlntDjnmvkV6bpNrnHCODdatsqU6 AmG9Nenh92/XBd+qaz0A5LrnbJ8AyvAgmY4xYewt405GVone8+jcT1q0gHil52qwmQSm 2c2ZhneaEi3INXe/FKH70zGWoUWTzIeeJiYlsyrRKw5s2rx2YNkCO1yhaQ8+smVtiGBc zYtA== X-Gm-Message-State: AOAM532D2Ez/yh1Yt1eBNEY3Upen9H5qFs9naX3xA8psmdpBkeF2iR1T O4lRgQP3GwU8W8c2DJ2USeoACNAGee8HD9dOJZ5WW4aAkEtcjm5jkwMMfpwYM0jQ35XaKwgfvJg 7obz94JaKrF1vIDmEmdJd4eOLiunSn2BF4VZM4urzMEJh2KirsU35Q/ELQHEsxOR1IiJn9iaHSn kxt4ACLxPzgjlh6qI9 X-Google-Smtp-Source: ABdhPJxUoacAYoBRc2lU1MnrO2thZNWlOT7k9ldUA5Uo6JdpNTbP0+ss+QIEqv7t+aG2BNl+L+GRew== X-Received: by 2002:a1f:2d10:: with SMTP id t16mr15067999vkt.36.1643906640835; Thu, 03 Feb 2022 08:44:00 -0800 (PST) Received: from localhost (host8.190-224-49.telecom.net.ar. [190.224.49.8]) by smtp.gmail.com with ESMTPSA id k203sm6696515vka.56.2022.02.03.08.43.56 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 03 Feb 2022 08:44:00 -0800 (PST) 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 v6 2/6] mm/mmzone: Tag pg_data_t with crypto capabilities Date: Thu, 3 Feb 2022 13:43:24 -0300 Message-Id: <20220203164328.203629-3-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220203164328.203629-1-martin.fernandez@eclypsium.com> References: <20220203164328.203629-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add a new member in the pg_data_t struct tell whether the node corresponding to that pg_data_t is able to do hardware memory encryption. This will be read from sysfs. Signed-off-by: Martin Fernandez Reviewed-by: Kees Cook --- include/linux/mmzone.h | 3 +++ mm/page_alloc.c | 1 + 2 files changed, 4 insertions(+) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 936dc0b6c226..cec51e7a01d9 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -871,6 +871,9 @@ typedef struct pglist_data { struct task_struct *kcompactd; bool proactive_compact_trigger; #endif + + bool crypto_capable; + /* * This is a per-node reserve of pages that are not available * to userspace allocations. diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c5952749ad40..8bcbd6fa0089 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -7592,6 +7592,7 @@ static void __init free_area_init_node(int nid) pgdat->node_id =3D nid; pgdat->node_start_pfn =3D start_pfn; pgdat->per_cpu_nodestats =3D NULL; + pgdat->crypto_capable =3D memblock_node_is_crypto_capable(nid); =20 pr_info("Initmem setup node %d [mem %#018Lx-%#018Lx]\n", nid, (u64)start_pfn << PAGE_SHIFT, --=20 2.30.2 From nobody Mon Jun 29 19:43:30 2026 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 6154CC433F5 for ; Thu, 3 Feb 2022 16:44:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352367AbiBCQoR (ORCPT ); Thu, 3 Feb 2022 11:44:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60646 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352356AbiBCQoJ (ORCPT ); Thu, 3 Feb 2022 11:44:09 -0500 Received: from mail-ua1-x92e.google.com (mail-ua1-x92e.google.com [IPv6:2607:f8b0:4864:20::92e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ED54FC06173E for ; Thu, 3 Feb 2022 08:44:08 -0800 (PST) Received: by mail-ua1-x92e.google.com with SMTP id p26so6159790uaa.11 for ; Thu, 03 Feb 2022 08:44:08 -0800 (PST) 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=Fi3rT5zncMeb0k62MKj5Wn1cLd6ugCHvnXJ1Eq5KCa0=; b=NvdHm8ZyWfi0qPRPM+5eaY3VcYdKTT5T5PTKPAIf5IKMvikxV+woDLhIxH25uoCdQw vHdVPqcx2Uu6lOdtf69jiorByv/Yvs+1n61gBbML04ly+vlppbwM04Q1IviA7SvPdgM0 ZBHQTLbQDi8OoNzNC3bp0w+LKaZICP5hjZFgM7zBPDJXVshnejKKVoSV+MV9bZ0y30uG S/fkfQqlnAbcmdf/neL6WdvadA6sSua07/0pJqxn+CmxEMHxNwUt/VZKiRAGeaF4Bt0U WZdx6403WNT+MsccRohZzeT9QgsL8y9KHpGOTq/infNJ27I5cwtTt0Gl61HrfXKptJum F1fQ== 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=Fi3rT5zncMeb0k62MKj5Wn1cLd6ugCHvnXJ1Eq5KCa0=; b=MIqYSDL6e3Enh5POXvzchHROD1t1HA7UU4s067JwFioYHTJ2+Dz1EA503W+JwHu8Nz R3i16kdm6AhabrKe6iHx/rDYMsrOhYg/t6oyXOwWdHXOcfWytueBytFE0OPuRPT6p8uP uzTbaXWnkqbAsv0TG02aS3DG0iWFqv0zUBF/7X6l+daXoYdISgnDoepzaAKVragr8lb2 jRdl1TPu9UXBPfgow+lqh+Dv3C3O7GB7x3qA7oAnevDGWkYwFJ15AFC8m+Rrx08ny1L6 VgWnM+KuyPEdngxbZBG1z3g59IyRwAlTJjcby1wTi1yo78F0AoG/6oPl21a4eHzvsFud I9og== X-Gm-Message-State: AOAM530mJZsoZoNaZsWKsZMfCUz4Q2bogydOCV6wwOMR+o/LiwtmMCOU 8bb7AUletJhgEKTYnH1pM3OmkVYKP/53Bew368GLTs6e3Zgoj00+7jCp49tMaiK36XIRJ+jlBVm 7cf7/e44Ue6tqzrz/YurJxzAebKYsl5GxSTLrF21ymtg5Ijom4yedG1bwZVRQi5ROT1Vm0F1xLR 96A02MU0Q4jDclAOw4 X-Google-Smtp-Source: ABdhPJzTU4dUSsxkR8M13OcbGpk/9wSKp/Q3vNcqDpl7kwLqhu0cZWStdgwP6MKmi2+t0WOgK4+gOA== X-Received: by 2002:a05:6102:32c3:: with SMTP id o3mr13405580vss.4.1643906647473; Thu, 03 Feb 2022 08:44:07 -0800 (PST) Received: from localhost (host8.190-224-49.telecom.net.ar. [190.224.49.8]) by smtp.gmail.com with ESMTPSA id p2sm7048949uao.1.2022.02.03.08.44.02 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 03 Feb 2022 08:44:07 -0800 (PST) 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 v6 3/6] x86/e820: Refactor range_update and range_remove Date: Thu, 3 Feb 2022 13:43:25 -0300 Message-Id: <20220203164328.203629-4-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220203164328.203629-1-martin.fernandez@eclypsium.com> References: <20220203164328.203629-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" __e820__range_update and e820__range_remove had a very similar 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. I propose a refactor of those functions, given that I need to create a similar one for this patchset. Add a function to modify a E820 table in a given range. This modification is done backed up by two helper structs: e820_entry_updater and e820_*_data. The first one, e820_entry_updater, carries 3 callbacks which function as the actions to take on the table. The other one, e820_*_data carries information needed by the callbacks, for example in the case of range_update it will carry the type that we are targeting. Signed-off-by: Martin Fernandez --- arch/x86/kernel/e820.c | 383 ++++++++++++++++++++++++++++++----------- 1 file changed, 283 insertions(+), 100 deletions(-) diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index bc0657f0deed..89b78c6b345b 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -459,144 +459,327 @@ static int __init append_e820_table(struct boot_e82= 0_entry *entries, u32 nr_entr return __append_e820_table(entries, nr_entries); } =20 +/** + * 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_remove_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; +}; + +/** + * e820_type_updater_data - Helper type for __e820__range_update(). + * @old_type: old_type parameter of __e820__range_update(). + * @new_type: new_type parameter of __e820__range_update(). + * + * This is intended to be used as the @data argument for the + * e820_entry_updater callbacks. + */ +struct e820_type_updater_data { + enum e820_type old_type; + enum e820_type new_type; +}; + +/** + * __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__range_update(struct e820_table *table, u64 start, u64 size, enum e= 820_type old_type, enum e820_type new_type) +__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; - unsigned int i; - u64 real_updated_size =3D 0; - - BUG_ON(old_type =3D=3D new_type); + u64 entry_end =3D entry->addr + entry->size; + u64 inner_start; + u64 inner_end; + u64 updated_size =3D 0; =20 if (size > (ULLONG_MAX - start)) size =3D ULLONG_MAX - start; =20 end =3D start + size; - printk(KERN_DEBUG "e820: update [mem %#010Lx-%#010Lx] ", start, end - 1); - e820_print_type(old_type); - pr_cont(" =3D=3D> "); - e820_print_type(new_type); - pr_cont("\n"); - - for (i =3D 0; i < table->nr_entries; i++) { - struct e820_entry *entry =3D &table->entries[i]; - u64 final_start, final_end; - u64 entry_end; + inner_start =3D max(start, entry->addr); + inner_end =3D 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 =3D inner_start - entry->addr; + /* Entry is on the right */ + } else { + /* Resize and move current section */ + entry->addr =3D inner_end; + entry->size =3D entry_end - inner_end; + } + /* Create new entry with intersected region */ + updater->new(table, inner_start, inner_end - inner_start, entry, data); =20 - if (entry->type !=3D old_type) - continue; + updated_size +=3D inner_end - inner_start; + } /* Else: [start, end) doesn't cover entry */ =20 - entry_end =3D entry->addr + entry->size; + return updated_size; +} =20 - /* Completely covered by new range? */ - if (entry->addr >=3D start && entry_end <=3D end) { - entry->type =3D new_type; - real_updated_size +=3D entry->size; - continue; - } +/** __e820__handle_range_update(): Helper function to update a 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. + * + * 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 =3D 0; + u64 end; + unsigned int i; =20 - /* New range is completely covered? */ - if (entry->addr < start && entry_end > end) { - __e820__range_add(table, start, size, new_type); - __e820__range_add(table, end, entry_end - end, entry->type); - entry->size =3D start - entry->addr; - real_updated_size +=3D size; - continue; - } + if (size > (ULLONG_MAX - start)) + size =3D ULLONG_MAX - start; =20 - /* Partially covered: */ - final_start =3D max(start, entry->addr); - final_end =3D min(end, entry_end); - if (final_start >=3D final_end) - continue; + end =3D start + size; =20 - __e820__range_add(table, final_start, final_end - final_start, new_type); + for (i =3D 0; i < table->nr_entries; i++) { + struct e820_entry *entry =3D &table->entries[i]; + u64 entry_end =3D entry->addr + entry->size; + + if (updater->should_update(data, entry)) { + /* Range completely covers entry */ + if (entry->addr >=3D start && entry_end <=3D end) { + updater->update(entry, data); + updated_size +=3D entry->size; + /* Entry completely covers range */ + } else if (start > entry->addr && end < entry_end) { + /* Resize current entry */ + entry->size =3D 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); + + updated_size +=3D size; + } else { + updated_size =3D + __e820__handle_intersected_range_update(table, start, size, + entry, updater, data); + } + } + } =20 - real_updated_size +=3D final_end - final_start; + return updated_size; +} =20 - /* - * Left range could be head or tail, so need to update - * its size first: - */ - entry->size -=3D final_end - final_start; - if (entry->addr < final_start) - continue; +static bool __init type_updater__should_update(const struct e820_entry *en= try, + const void *data) +{ + struct e820_type_updater_data *type_updater_data =3D + (struct e820_type_updater_data *)data; =20 - entry->addr =3D final_end; - } - return real_updated_size; + return entry->type =3D=3D type_updater_data->old_type; } =20 -u64 __init e820__range_update(u64 start, u64 size, enum e820_type old_type= , enum e820_type new_type) +static void __init type_updater__update(struct e820_entry *entry, + const void *data) { - return __e820__range_update(e820_table, start, size, old_type, new_type); + struct e820_type_updater_data *type_updater_data =3D + (struct e820_type_updater_data *)data; + + entry->type =3D type_updater_data->new_type; } =20 -static u64 __init e820__range_update_kexec(u64 start, u64 size, enum e820_= type old_type, enum e820_type new_type) +static void __init type_updater__new(struct e820_table *table, u64 new_sta= rt, + u64 new_size, + const struct e820_entry *original, + const void *data) { - return __e820__range_update(e820_table_kexec, start, size, old_type, new_= type); + struct e820_type_updater_data *type_updater_data =3D + (struct e820_type_updater_data *)data; + + __e820__range_add(table, new_start, new_size, + type_updater_data->new_type); } =20 -/* 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) +static u64 __init __e820__range_update(struct e820_table *table, u64 start, + u64 size, enum e820_type old_type, + enum e820_type new_type) { - int i; - u64 end; - u64 real_removed_size =3D 0; + struct e820_entry_updater updater =3D { + .should_update =3D type_updater__should_update, + .update =3D type_updater__update, + .new =3D type_updater__new + }; =20 - if (size > (ULLONG_MAX - start)) - size =3D ULLONG_MAX - start; + struct e820_type_updater_data data =3D { + .old_type =3D old_type, + .new_type =3D new_type + }; =20 - end =3D start + size; - printk(KERN_DEBUG "e820: remove [mem %#010Lx-%#010Lx] ", start, end - 1); - if (check_type) - e820_print_type(old_type); + BUG_ON(old_type =3D=3D new_type); + + printk(KERN_DEBUG "e820: update [mem %#018Lx-%#018Lx] ", start, + start + size - 1); + e820_print_type(old_type); + pr_cont(" =3D=3D> "); + e820_print_type(new_type); pr_cont("\n"); =20 - for (i =3D 0; i < e820_table->nr_entries; i++) { - struct e820_entry *entry =3D &e820_table->entries[i]; - u64 final_start, final_end; - u64 entry_end; + return __e820__handle_range_update(table, start, size, &updater, &data); +} =20 - if (check_type && entry->type !=3D old_type) - continue; +static bool __init remover__should_update(const struct e820_entry *entry, + const void *data) +{ + struct e820_remover_data *remover_data =3D + (struct e820_remover_data *)data; =20 - entry_end =3D entry->addr + entry->size; + return !remover_data->check_type || + entry->type =3D=3D remover_data->old_type; +} =20 - /* Completely covered? */ - if (entry->addr >=3D start && entry_end <=3D end) { - real_removed_size +=3D entry->size; - memset(entry, 0, sizeof(*entry)); - continue; - } +static void __init remover__update(struct e820_entry *entry, const void *d= ata) +{ + memset(entry, 0, sizeof(*entry)); +} =20 - /* Is the new range completely covered? */ - if (entry->addr < start && entry_end > end) { - e820__range_add(end, entry_end - end, entry->type); - entry->size =3D start - entry->addr; - real_removed_size +=3D 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) +{ +} =20 - /* Partially covered: */ - final_start =3D max(start, entry->addr); - final_end =3D min(end, entry_end); - if (final_start >=3D 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 =3D { + .should_update =3D remover__should_update, + .update =3D remover__update, + .new =3D remover__new + }; + + struct e820_remover_data data =3D { + .check_type =3D check_type, + .old_type =3D old_type + }; + + printk(KERN_DEBUG "e820: remove [mem %#018Lx-%#018Lx] ", start, + start + size - 1); + if (check_type) + e820_print_type(old_type); + pr_cont("\n"); =20 - real_removed_size +=3D final_end - final_start; + return __e820__handle_range_update(e820_table, start, size, &updater, + &data); +} =20 - /* - * Left range could be head or tail, so need to update - * the size first: - */ - entry->size -=3D final_end - final_start; - if (entry->addr < final_start) - continue; +/** + * e820__range_update() - Update the type of a given address range in + * e820_table. + * @start: Start of the range. + * @size: Size of the range. + * @old_type: Type that we want to change. + * @new_type: New type to replace @old_type. + * + * Update type of addresses in [@start, @start + @size) from @old_type + * to @new_type in e820_table. + * + * Return: The size updated. + */ +u64 __init e820__range_update(u64 start, u64 size, enum e820_type old_type, + enum e820_type new_type) +{ + return __e820__range_update(e820_table, start, size, old_type, new_type); +} =20 - entry->addr =3D final_end; - } - return real_removed_size; +/** + * e820__range_update_kexec() - Update the type of a given address + * range in e820_table_kexec. + * @start: Start of the range. + * @size: Size of the range. + * @old_type: Type that we want to change. + * @new_type: New type to replace @old_type. + * + * Update type of addresses in [@start, @start + @size) from @old_type + * to @new_type in e820_table_kexec. + * + * Return: The size updated. + */ +static u64 __init e820__range_update_kexec(u64 start, u64 size, + enum e820_type old_type, + enum e820_type new_type) +{ + return __e820__range_update(e820_table_kexec, start, size, old_type, new_= type); } =20 void __init e820__update_table_print(void) --=20 2.30.2 From nobody Mon Jun 29 19:43:30 2026 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 E9590C433EF for ; Thu, 3 Feb 2022 16:44:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352377AbiBCQoU (ORCPT ); Thu, 3 Feb 2022 11:44:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60676 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352359AbiBCQoP (ORCPT ); Thu, 3 Feb 2022 11:44:15 -0500 Received: from mail-ua1-x92a.google.com (mail-ua1-x92a.google.com [IPv6:2607:f8b0:4864:20::92a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7204CC06173D for ; Thu, 3 Feb 2022 08:44:14 -0800 (PST) Received: by mail-ua1-x92a.google.com with SMTP id b37so6161625uad.12 for ; Thu, 03 Feb 2022 08:44:14 -0800 (PST) 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=yjdK5U5Da9cqL6OL8NEqAW4tX/0WDFOVYE3N0Y7mjjg=; b=RnHSE2ec2sy3mA4qRJGiuwYWc3KmdYerQlEAtmAWqgljRdYp/FHmkV11qBJPmqY4hI 9PJJnVDjSOhF+R0a/Be7S6KXoosBDsqd0/nw2NkuWgQ6aA0W7R38t390QoRmY4vua4kr snytvlWjEUY9Fkyf5CjPalbYvWzn/RbuGow8QXySbzQ0cJD0P5xAS/Fepm7M+sX8rulM 3vDcgzZd/fiJW/CQT8T9xOiDYDlyDqAL0XKfr+adDMFfSMHCNg5taonwfHtBBKIPm8rx t78P10CyuzuchirzZch6Vf17N4vuzDmRNAf6D5vEB2RYot5cPpubKjh4jBIHTO239Zct rzRA== 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=yjdK5U5Da9cqL6OL8NEqAW4tX/0WDFOVYE3N0Y7mjjg=; b=mCOp6k0ZpWRcHAg/afztT70ap9cG2YHti3lc5cXVIxWakGaqgBPVgwhBMn5Qe+HQe5 96H309MDfjIxNKtBljCvoOJ3Cec5Hm1unZJrdcf2vxizI7R7AR3/tdE7E/4cBx8QS1C3 n0MCtddsKsK0eqzFNTViVYMWVGONtrY2bNzvAIVSnu6AvAzfOtF/W6d43ZxmHGCFkf/u zg+irZ/VV3od+ZSxER/Dba0n0DENUozYiZmXqkaCtVQOdHPIAQelpDX8RmmMoIsYmV2O XEfKvCMBOnpIMjYiLYEp12Cp8cFph31wp05ubTixkRbUqBsVu6D5gB5f6D6u6F9URfjn 2RXA== X-Gm-Message-State: AOAM530oV9VkgVRTG77gfEF3ZrIohYBtTfkcRmIV20zCQUmxgNvJ3sWC KDo85p24CD8JEHNu/4a1SCThzTJRufiXp4prLiswQGryp/Fjk9yX6JDgrhxzVxCqgmuWvnSCAOI yD3Yf30YuEHiQsRJWUmocz408b8cJdZEBV3wJh5nuM0rM9M4LtqYkupMy/FIH4ekibWQLkU/bVf Tsmf3/ZPydWHmN0nPz X-Google-Smtp-Source: ABdhPJxfw66WC7p5te/X+pajwCMpJVrLZDihaKaoVnPruFsPWW9RLMsUn/DfHzIlf64y+VH5gAesjA== X-Received: by 2002:a05:6102:f08:: with SMTP id v8mr14207630vss.3.1643906653209; Thu, 03 Feb 2022 08:44:13 -0800 (PST) Received: from localhost (host8.190-224-49.telecom.net.ar. [190.224.49.8]) by smtp.gmail.com with ESMTPSA id u70sm3653044vsu.10.2022.02.03.08.44.09 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 03 Feb 2022 08:44:12 -0800 (PST) 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 v6 4/6] x86/e820: Tag e820_entry with crypto capabilities Date: Thu, 3 Feb 2022 13:43:26 -0300 Message-Id: <20220203164328.203629-5-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220203164328.203629-1-martin.fernandez@eclypsium.com> References: <20220203164328.203629-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add a new enum for crypto capabilities. Add a new member in e820_entry to hold whether an entry is able to do hardware memory encryption or not. Add a new function e820__range_set_crypto_capable to mark all the entries in a range of addresses as encryptable. This will be called when initializing EFI. Change e820__update_table to handle merging and overlap problems taking into account crypto_capable. Signed-off-by: Martin Fernandez --- arch/x86/include/asm/e820/api.h | 1 + arch/x86/include/asm/e820/types.h | 12 +++- arch/x86/kernel/e820.c | 114 ++++++++++++++++++++++++++++-- 3 files changed, 119 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/e820/api.h b/arch/x86/include/asm/e820/ap= i.h index e8f58ddd06d9..4b3b01fafdd1 100644 --- a/arch/x86/include/asm/e820/api.h +++ b/arch/x86/include/asm/e820/api.h @@ -17,6 +17,7 @@ extern bool e820__mapped_all(u64 start, u64 end, enum e82= 0_type type); extern void e820__range_add (u64 start, u64 size, enum e820_type type); extern u64 e820__range_update(u64 start, u64 size, enum e820_type old_typ= e, enum e820_type new_type); extern u64 e820__range_remove(u64 start, u64 size, enum e820_type old_typ= e, bool check_type); +extern u64 e820__range_set_crypto_capable(u64 start, u64 size); =20 extern void e820__print_table(char *who); extern int e820__update_table(struct e820_table *table); diff --git a/arch/x86/include/asm/e820/types.h b/arch/x86/include/asm/e820/= types.h index 314f75d886d0..aef03c665f5e 100644 --- a/arch/x86/include/asm/e820/types.h +++ b/arch/x86/include/asm/e820/types.h @@ -46,6 +46,11 @@ enum e820_type { E820_TYPE_RESERVED_KERN =3D 128, }; =20 +enum e820_crypto_capabilities { + E820_NOT_CRYPTO_CAPABLE =3D 0, + E820_CRYPTO_CAPABLE =3D 1, +}; + /* * A single E820 map entry, describing a memory range of [addr...addr+size= -1], * of 'type' memory type: @@ -53,9 +58,10 @@ enum e820_type { * (We pack it because there can be thousands of them on large systems.) */ struct e820_entry { - u64 addr; - u64 size; - enum e820_type type; + u64 addr; + u64 size; + enum e820_type type; + enum e820_crypto_capabilities crypto_capable; } __attribute__((packed)); =20 /* diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 89b78c6b345b..098882d02120 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -163,7 +163,9 @@ int e820__get_entry_type(u64 start, u64 end) /* * Add a memory region to the kernel E820 map. */ -static void __init __e820__range_add(struct e820_table *table, u64 start, = u64 size, enum e820_type type) +static void __init __e820__range_add(struct e820_table *table, u64 start, + u64 size, enum e820_type type, + enum e820_crypto_capabilities crypto_capable) { int x =3D table->nr_entries; =20 @@ -176,12 +178,13 @@ static void __init __e820__range_add(struct e820_tabl= e *table, u64 start, u64 si table->entries[x].addr =3D start; table->entries[x].size =3D size; table->entries[x].type =3D type; + table->entries[x].crypto_capable =3D crypto_capable; table->nr_entries++; } =20 void __init e820__range_add(u64 start, u64 size, enum e820_type type) { - __e820__range_add(e820_table, start, size, type); + __e820__range_add(e820_table, start, size, type, E820_NOT_CRYPTO_CAPABLE); } =20 static void __init e820_print_type(enum e820_type type) @@ -211,6 +214,8 @@ void __init e820__print_table(char *who) e820_table->entries[i].addr + e820_table->entries[i].size - 1); =20 e820_print_type(e820_table->entries[i].type); + if (e820_table->entries[i].crypto_capable =3D=3D E820_CRYPTO_CAPABLE) + pr_cont("; crypto-capable"); pr_cont("\n"); } } @@ -327,6 +332,7 @@ int __init e820__update_table(struct e820_table *table) unsigned long long last_addr; u32 new_nr_entries, overlap_entries; u32 i, chg_idx, chg_nr; + enum e820_crypto_capabilities current_crypto, last_crypto; =20 /* If there's only one memory region, don't bother: */ if (table->nr_entries < 2) @@ -367,6 +373,7 @@ int __init e820__update_table(struct e820_table *table) new_nr_entries =3D 0; /* Index for creating new map entries */ last_type =3D 0; /* Start with undefined memory type */ last_addr =3D 0; /* Start with 0 as last starting address */ + last_crypto =3D E820_NOT_CRYPTO_CAPABLE; =20 /* Loop through change-points, determining effect on the new map: */ for (chg_idx =3D 0; chg_idx < chg_nr; chg_idx++) { @@ -388,13 +395,19 @@ int __init e820__update_table(struct e820_table *tabl= e) * 1=3Dusable, 2,3,4,4+=3Dunusable) */ current_type =3D 0; + current_crypto =3D E820_CRYPTO_CAPABLE; for (i =3D 0; i < overlap_entries; i++) { + if (overlap_list[i]->crypto_capable < current_crypto) + current_crypto =3D overlap_list[i]->crypto_capable; + if (overlap_list[i]->type > current_type) current_type =3D overlap_list[i]->type; } =20 /* Continue building up new map based on this information: */ - if (current_type !=3D last_type || e820_nomerge(current_type)) { + if (current_type !=3D last_type || + current_crypto !=3D last_crypto || + e820_nomerge(current_type)) { if (last_type !=3D 0) { new_entries[new_nr_entries].size =3D change_point[chg_idx]->addr - las= t_addr; /* Move forward only if the new size was non-zero: */ @@ -406,9 +419,12 @@ int __init e820__update_table(struct e820_table *table) if (current_type !=3D 0) { new_entries[new_nr_entries].addr =3D change_point[chg_idx]->addr; new_entries[new_nr_entries].type =3D current_type; + new_entries[new_nr_entries].crypto_capable =3D current_crypto; + last_addr =3D change_point[chg_idx]->addr; } last_type =3D current_type; + last_crypto =3D current_crypto; } } =20 @@ -505,6 +521,19 @@ struct e820_type_updater_data { enum e820_type new_type; }; =20 +/** + * e820_crypto_updater_data - Helper type for + * __e820__range_update_crypto(). + * @crypto_capable: crypto_capable parameter of + * __e820__range_update_crypto(). + * + * This is intended to be used as the @data argument for the + * e820_entry_updater callbacks. + */ +struct e820_crypto_updater_data { + enum e820_crypto_capabilities crypto_capable; +}; + /** * __e820__handle_intersected_range_update() - Helper function for * __e820__handle_range_update(). @@ -615,7 +644,8 @@ __e820__handle_range_update(struct e820_table *table, * of the current entry */ __e820__range_add(table, end, entry_end - end, - entry->type); + entry->type, + entry->crypto_capable); =20 updated_size +=3D size; } else { @@ -656,7 +686,7 @@ static void __init type_updater__new(struct e820_table = *table, u64 new_start, (struct e820_type_updater_data *)data; =20 __e820__range_add(table, new_start, new_size, - type_updater_data->new_type); + type_updater_data->new_type, original->crypto_capable); } =20 static u64 __init __e820__range_update(struct e820_table *table, u64 start, @@ -686,6 +716,62 @@ static u64 __init __e820__range_update(struct e820_tab= le *table, u64 start, return __e820__handle_range_update(table, start, size, &updater, &data); } =20 +static bool __init crypto_updater__should_update(const struct e820_entry *= entry, + const void *data) +{ + struct e820_crypto_updater_data *crypto_updater_data =3D + (struct e820_crypto_updater_data *)data; + + return crypto_updater_data->crypto_capable !=3D entry->crypto_capable; +} + +static void __init crypto_updater__update(struct e820_entry *entry, + const void *data) +{ + struct e820_crypto_updater_data *crypto_updater_data =3D + (struct e820_crypto_updater_data *)data; + + entry->crypto_capable =3D crypto_updater_data->crypto_capable; +} + +static void __init crypto_updater__new(struct e820_table *table, u64 new_s= tart, + u64 new_size, + const struct e820_entry *original, + const void *data) +{ + struct e820_crypto_updater_data *crypto_updater_data =3D + (struct e820_crypto_updater_data *)data; + + __e820__range_add(table, new_start, new_size, original->type, + crypto_updater_data->crypto_capable); +} + +static u64 __init +__e820__range_update_crypto(struct e820_table *table, u64 start, u64 size, + enum e820_crypto_capabilities crypto_capable) +{ + struct e820_entry_updater updater =3D { + .should_update =3D crypto_updater__should_update, + .update =3D crypto_updater__update, + .new =3D crypto_updater__new + }; + + struct e820_crypto_updater_data data =3D { + .crypto_capable =3D crypto_capable, + }; + + printk(KERN_DEBUG "e820: crypto update [mem %#018Lx-%#018Lx]", start, + start + size - 1); + pr_cont(" =3D=3D> "); + if (crypto_capable =3D=3D E820_CRYPTO_CAPABLE) + pr_cont("crypto capable"); + else + pr_cont("not crypto capable"); + pr_cont("\n"); + + return __e820__handle_range_update(table, start, size, &updater, &data); +} + static bool __init remover__should_update(const struct e820_entry *entry, const void *data) { @@ -782,6 +868,22 @@ static u64 __init e820__range_update_kexec(u64 start, = u64 size, return __e820__range_update(e820_table_kexec, start, size, old_type, new_= type); } =20 +/** + * e820__range_set_crypto_capable() - Set %E820_CRYPTO_CAPABLE to a + * given range of addresses in e820_table. + * @start: Start of the range. + * @size: Size of the range. + * + * Set %E820_CRYPTO_CAPABLE to [@start, @start + @size) in e820_table. + * + * Return: The size updated. + */ +u64 __init e820__range_set_crypto_capable(u64 start, u64 size) +{ + return __e820__range_update_crypto(e820_table, start, size, + E820_CRYPTO_CAPABLE); +} + void __init e820__update_table_print(void) { if (e820__update_table(e820_table)) @@ -1505,6 +1607,8 @@ void __init e820__memblock_setup(void) continue; =20 memblock_add(entry->addr, entry->size); + if (entry->crypto_capable =3D=3D E820_CRYPTO_CAPABLE) + memblock_mark_crypto_capable(entry->addr, entry->size); } =20 /* Throw away partial pages: */ --=20 2.30.2 From nobody Mon Jun 29 19:43:30 2026 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 4FFBEC43217 for ; Thu, 3 Feb 2022 16:44:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352369AbiBCQo2 (ORCPT ); Thu, 3 Feb 2022 11:44:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60714 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352381AbiBCQoV (ORCPT ); Thu, 3 Feb 2022 11:44:21 -0500 Received: from mail-vk1-xa2d.google.com (mail-vk1-xa2d.google.com [IPv6:2607:f8b0:4864:20::a2d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8E175C06173E for ; Thu, 3 Feb 2022 08:44:21 -0800 (PST) Received: by mail-vk1-xa2d.google.com with SMTP id j185so2091414vkc.1 for ; Thu, 03 Feb 2022 08:44:21 -0800 (PST) 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=IAiLk5cjQwcE3yLS3aO2GBCqcyaetSmqrMvYHWmRcTBrX/70H06j9PR2aE3QGP81gN G6QDkvipCsGgjSUtRGArhWJu9iDWKOYWnm+NZ0aqk4cri2wqtuUQX+b9q3EK3qLf7feX OImmnQkBiMNjk2/7Ue9/B8Qdinvi+e/rlfFOS1vMUliTuXgm65EiqOAZE9CaQY4tGH/U /17cWo3icgYBFxnClGbVhoptcy+1QRAjpqIMCkUQhjxF94o8InjEYUfRnEDRxY6mI8V3 60dkSPCH/hnp20RoME00w3RlqarwXBsRUPrQ7hYsR3fup3yBWAysWmRuspyPg2EBrkB9 r+AQ== 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=YS+cW0eBxZ5N+ZlC6ceMgAh9qyTsVrDBJTJiDCvvtV4fwnpXfMYzJz2cbLkvsEq+sA TdpfatTJXBLQP4W9sn2rRPZxy3/jIIBu6S84leW+U534+bf2qIuwQ8bm4nXUG1x0yU6m wc1cVQNCkbk1p3Ie7E+BLPhYx/QuZKbPogyPL+tUHkiSZBUNV2FNIEcuvoCcxt/Fj3wn jZVSbAyMWiYXZRMEg8DEe6baS3MqpgOFlVss2NyuojDFgajin74H0Kr4aLM6bRuohfcg HUL0tQVAiMKDAMxxJojBqNA5KQCzJ3G+w9Q2HGAHPrSZQtHCcn8L8Rb6IqNQ0DSLnJdF ChLA== X-Gm-Message-State: AOAM531Fyrc4YMSYtZT/cPPbpUN7lPEzcZATy2SSugLMiRXZ32+Wdq6M e8ZvplfirMyiWqzy1zObq9XVI2OFLEDxOp6IgbQ9esIbbLs/DPPGexF60zE7Ziz8CW9iRz70aet eiQt3azTPrndjn+WmHo8PUHoGp0rLpNemgdUjkjPTJ0E2ZAsRKrqVSc/4mmUL1hcDxF4lBHE3Vv +UPKrssL+EV643HETY X-Google-Smtp-Source: ABdhPJzsOFFOqxgDzTCzuaTzUcSCoJoy32VcScNJTJMZP7zNyU9OfyuKOow2hpJD7GfcAiCruPNRVA== X-Received: by 2002:a05:6122:c90:: with SMTP id ba16mr15282992vkb.39.1643906660499; Thu, 03 Feb 2022 08:44:20 -0800 (PST) Received: from localhost (host8.190-224-49.telecom.net.ar. [190.224.49.8]) by smtp.gmail.com with ESMTPSA id s11sm6623102vke.47.2022.02.03.08.44.15 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 03 Feb 2022 08:44:20 -0800 (PST) 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 v6 5/6] x86/efi: Tag e820_entries as crypto capable from EFI memmap Date: Thu, 3 Feb 2022 13:43:27 -0300 Message-Id: <20220203164328.203629-6-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220203164328.203629-1-martin.fernandez@eclypsium.com> References: <20220203164328.203629-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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) } =20 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_tab= le_type_t *arch_tables) return ret; } =20 +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 >=3D E820_MAX_ENTRIES) { + pr_err_once("E820 table is not large enough to fit EFI memmap; not marki= ng 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(); =20 + /* + * 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(); } --=20 2.30.2 From nobody Mon Jun 29 19:43:30 2026 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 B4648C433F5 for ; Thu, 3 Feb 2022 16:44:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352390AbiBCQod (ORCPT ); Thu, 3 Feb 2022 11:44:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60740 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352379AbiBCQo1 (ORCPT ); Thu, 3 Feb 2022 11:44:27 -0500 Received: from mail-ua1-x936.google.com (mail-ua1-x936.google.com [IPv6:2607:f8b0:4864:20::936]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 43125C06173D for ; Thu, 3 Feb 2022 08:44:27 -0800 (PST) Received: by mail-ua1-x936.google.com with SMTP id a24so6167503uat.10 for ; Thu, 03 Feb 2022 08:44:27 -0800 (PST) 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=/7hWGiKDX/+3TtHvDCLSMJlu4NmyHYy7nVm6Glu5jcs=; b=Eu44Mg8zNIVsl+UBg0lHCou2bGR731muhWBsGIFlH7Qlfig/tH9EjGG7LhYDeVUgL2 yBKfPclwTyg18UZrOiqfuJ89i8XybLNqTaYSX/a4KtBkhWzz5k8noCv5qKrQnf7pz9gC cU9EIuCV0fRK8UzYYfyJ83sxVUdyV2whm2zfukAd37PEkif+0OQrFVjVtJRfk/NpB5kF aTGPNskbxUyxI7LLEMPrnqlI95zdXOWkLpELHRbx4BnCz2oqk41Y/TO4YHXrNBFYCbhD etxqFqFShnXPHvrKvugW+xoT0rdqJ0frp0xn6PltLCnhV9Fkya4hBOscS61TtYtWobdj h4pQ== 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=/7hWGiKDX/+3TtHvDCLSMJlu4NmyHYy7nVm6Glu5jcs=; b=45PS7qrBzUkkItOzyf/BfNZy1pZmK9BgA82vJd3quiSE/D6yEm4AqJxeWvjF1yMZxY LDpoApJOmJ18XxGcrfrVkawOekzZ6X9yw+whGSjb5b5K6diTyJqXycSLoEKMxb2RgS2k DcU6JcutenCESOtkNmPeRofiCUVflY09K+Xj41Nlh8TwHg5fGHMhHtv31U+kpcTiZuAu UEnSqz5NDTsQEyyg/9/gV8+7FgSyFlLOmToA5+Y3pc5zZJAvMO0vy/mu1Hu0vdsP1LpJ fy2ORC2X5/2iYPdM3MFRXE9x4nZnsXrVbfFDcHiqFf0SjBgmjq+NwkfnylKOJeci1kQ9 Sk3Q== X-Gm-Message-State: AOAM5308MbIiUm9lDQkMy7fR9W9misNgh9OwXbnBGCX5SpJmbk2B5q7x d8vsyqg9OGYXwKesNC14mOKGalyy80w81AuWxChbNKh6JSH/nlTbkuF03eUYwR6xGGF7fSMV57o K1ibnwtTZ4o6lQBmjjq26SzvGKAfvy/CK3yHXKuE9ZS2k0zfxQx3z49q5mITvdawX5pZRZNsIy1 oFFh9rd79txpLpKgP5 X-Google-Smtp-Source: ABdhPJx2HB4OlovRK80h8tYU9Mdgc8buyu05GDejH1rOLWTHA+JswrW0YVKJpoDXnPTHBnmidcJ4GQ== X-Received: by 2002:a67:fd55:: with SMTP id g21mr14698421vsr.86.1643906666202; Thu, 03 Feb 2022 08:44:26 -0800 (PST) Received: from localhost (host8.190-224-49.telecom.net.ar. [190.224.49.8]) by smtp.gmail.com with ESMTPSA id m185sm6362545vke.30.2022.02.03.08.44.22 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 03 Feb 2022 08:44:26 -0800 (PST) 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 v6 6/6] drivers/node: Show in sysfs node's crypto capabilities Date: Thu, 3 Feb 2022 13:43:28 -0300 Message-Id: <20220203164328.203629-7-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220203164328.203629-1-martin.fernandez@eclypsium.com> References: <20220203164328.203629-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Show in each node in sysfs if its memory is able to do be encrypted by the CPU, ie. if all its memory is marked with EFI_MEMORY_CPU_CRYPTO in the EFI memory map. Signed-off-by: Martin Fernandez --- Documentation/ABI/testing/sysfs-devices-node | 10 ++++++++++ drivers/base/node.c | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-devices-node diff --git a/Documentation/ABI/testing/sysfs-devices-node b/Documentation/A= BI/testing/sysfs-devices-node new file mode 100644 index 000000000000..0d1fd86c9faf --- /dev/null +++ b/Documentation/ABI/testing/sysfs-devices-node @@ -0,0 +1,10 @@ +What: /sys/devices/system/node/nodeX/crypto_capable +Date: February 2022 +Contact: Martin Fernandez +Users: fwupd (https://fwupd.org) +Description: + This value is 1 if all system memory in this node is + marked with EFI_MEMORY_CPU_CRYPTO, indicating that the + system memory is capable of being protected with the + CPU=E2=80=99s memory cryptographic capabilities. It is 0 + otherwise. \ No newline at end of file diff --git a/drivers/base/node.c b/drivers/base/node.c index 87acc47e8951..dabaed997ecd 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -560,11 +560,21 @@ static ssize_t node_read_distance(struct device *dev, } static DEVICE_ATTR(distance, 0444, node_read_distance, NULL); =20 +static ssize_t crypto_capable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pglist_data *pgdat =3D NODE_DATA(dev->id); + + return sysfs_emit(buf, "%d\n", pgdat->crypto_capable); +} +static DEVICE_ATTR_RO(crypto_capable); + static struct attribute *node_dev_attrs[] =3D { &dev_attr_meminfo.attr, &dev_attr_numastat.attr, &dev_attr_distance.attr, &dev_attr_vmstat.attr, + &dev_attr_crypto_capable.attr, NULL }; =20 --=20 2.30.2