From mboxrd@z Thu Jan 1 00:00:00 1970 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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7FDDEC433EF for ; Thu, 16 Dec 2021 19:24:34 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id E1DA36B007B; Thu, 16 Dec 2021 14:23:32 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id DCDFF6B007D; Thu, 16 Dec 2021 14:23:32 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id C6E716B007E; Thu, 16 Dec 2021 14:23:32 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0240.hostedemail.com [216.40.44.240]) by kanga.kvack.org (Postfix) with ESMTP id B98346B007B for ; Thu, 16 Dec 2021 14:23:32 -0500 (EST) Received: from smtpin04.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with ESMTP id 822B68249980 for ; Thu, 16 Dec 2021 19:23:22 +0000 (UTC) X-FDA: 78924631044.04.E5EBC68 Received: from mail-qk1-f177.google.com (mail-qk1-f177.google.com [209.85.222.177]) by imf25.hostedemail.com (Postfix) with ESMTP id 0A8D4A0013 for ; Thu, 16 Dec 2021 19:23:16 +0000 (UTC) Received: by mail-qk1-f177.google.com with SMTP id de30so12128qkb.0 for ; Thu, 16 Dec 2021 11:23:22 -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=W+BCPwrkfsgMMS4oXA2uOS9qbqDP/1NzYAX0XstAOPU=; b=LtMC1dg5tVLwMXBFPf+v2n/bdM2vXwbFTYBALQLLbgL+Tlyt8UqqSFYRBzZgm5hJtB PlN9EoluPLQvdJOY1pAMweK0lbIVZN8tv1l9JtokgxAo6hU8/H6xtll2Pc2Upo+goFOd IOzRMC5ktdEL29SjrUNVuti5Hw3XGZOFAjfgHYuYhrp6uZBa60WKCyvqAGbtc/2E37IY dkkZvXMhgQz9PXmp4tE09PEthLgecsUlx/WeHPjn3HZEJW1jLutVC8OLtDvEnCZMkTDE /Zcxv1WFToNIVEINQRWKB+yc+eGSSXfF4SwV1spENCBEoceBNpLiH/UEeNgBbM7TvxAy Z31Q== 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=W+BCPwrkfsgMMS4oXA2uOS9qbqDP/1NzYAX0XstAOPU=; b=DC0U4wsm0wE0OebWs0VarAukS69LbE47v8PAE3cMrD9RA/Uej/buWW7rn6xdJZPH6m WWbg6sdo8ZwlJxQ8qrrpa3n0xa9av2yX6/P+gSuuRSXUa73IL0em5yS3CnVy7Y1Zq457 RGOKE7UeZq1B/5PBisUDwJwdmna+5EqbpIFb2is00FGcIsbIcNrtSf/5R2fqVkRRYlhS xHdXlMw5HeNPslOgrNYIzgTSQyt3gMRPsKql7jlTn3NSDjoCOGK52QgIuI9uBjxS2ORS 1KUu7AtfeFrjH42hFSBYmwhPbOyxEPjFh2poBh1xkEb3cQB9XLRFdPwYw1PIhQbgqYBt 5gfg== X-Gm-Message-State: AOAM533kkBjMdnPAlGPM5nEEjojseQmpwBFL5A7BiTzwnon9sIrXF1rI BtrieJh/rAEllhyYXAGHRe97VQ== X-Google-Smtp-Source: ABdhPJyII4TMuf9tlEyytZBN5v/y4Y2dwyfW7UaFoDz3QyD92ZYPmat6ljjCCH5MYp4igQxgvQkT6g== X-Received: by 2002:a05:620a:4f6:: with SMTP id b22mr12857484qkh.98.1639682601499; Thu, 16 Dec 2021 11:23:21 -0800 (PST) Received: from localhost (7-153-16-190.fibertel.com.ar. [190.16.153.7]) by smtp.gmail.com with ESMTPSA id bp38sm3383460qkb.66.2021.12.16.11.23.16 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 16 Dec 2021 11:23:21 -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, Martin Fernandez Subject: [PATCH v4 3/5] x86/e820: Tag e820_entry with crypto capabilities Date: Thu, 16 Dec 2021 16:22:20 -0300 Message-Id: <20211216192222.127908-4-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211216192222.127908-1-martin.fernandez@eclypsium.com> References: <20211216192222.127908-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 X-Rspamd-Queue-Id: 0A8D4A0013 X-Stat-Signature: 4j1b6oib476egt5rhg9oakrbpaay1mi9 Authentication-Results: imf25.hostedemail.com; dkim=pass header.d=eclypsium.com header.s=google header.b=LtMC1dg5; dmarc=pass (policy=quarantine) header.from=eclypsium.com; spf=pass (imf25.hostedemail.com: domain of martin.fernandez@eclypsium.com designates 209.85.222.177 as permitted sender) smtp.mailfrom=martin.fernandez@eclypsium.com X-Rspamd-Server: rspam02 X-HE-Tag: 1639682596-655989 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Add a new member in e820_entry to hold whether an entry is able to do hardware memory encryption or not. Add a new argument to __e820__range_add to accept this new crypto_capable. Add a new argument to __e820__update_range to be able to change a region's crypto_capable member. Also, change its behavior a little, before if you wanted to update a region with its same type it was a BUG_ON; now if you call it with both old_type and new_type equals, then the function won't change the types, just crypto_capable. Change e820__update_table to handle merging and overlap problems taking into account crypto_capable. Add a function to mark a range as crypto, using __e820__range_update in the background. This will be called when initializing EFI. Signed-off-by: Martin Fernandez --- arch/x86/include/asm/e820/api.h | 1 + arch/x86/include/asm/e820/types.h | 1 + arch/x86/kernel/e820.c | 59 ++++++++++++++++++++++++------- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/e820/api.h b/arch/x86/include/asm/e820/= api.h index e8f58ddd06d9..677dcbabcc8b 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 e= 820_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_t= ype, enum e820_type new_type); extern u64 e820__range_remove(u64 start, u64 size, enum e820_type old_t= ype, bool check_type); +extern u64 e820__range_mark_as_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/e82= 0/types.h index 314f75d886d0..7b510dffd3b9 100644 --- a/arch/x86/include/asm/e820/types.h +++ b/arch/x86/include/asm/e820/types.h @@ -56,6 +56,7 @@ struct e820_entry { u64 addr; u64 size; enum e820_type type; + u8 crypto_capable; } __attribute__((packed)); =20 /* diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index bc0657f0deed..001d64686938 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -163,7 +163,7 @@ 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, u8 crypto_capable) { int x =3D table->nr_entries; =20 @@ -176,12 +176,13 @@ static void __init __e820__range_add(struct e820_ta= ble *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, 0); } =20 static void __init e820_print_type(enum e820_type type) @@ -211,6 +212,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) + pr_cont("; crypto-capable"); pr_cont("\n"); } } @@ -327,6 +330,7 @@ int __init e820__update_table(struct e820_table *tabl= e) unsigned long long last_addr; u32 new_nr_entries, overlap_entries; u32 i, chg_idx, chg_nr; + u8 current_crypto, last_crypto; =20 /* If there's only one memory region, don't bother: */ if (table->nr_entries < 2) @@ -367,6 +371,7 @@ int __init e820__update_table(struct e820_table *tabl= e) 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 0; =20 /* Loop through change-points, determining effect on the new map: */ for (chg_idx =3D 0; chg_idx < chg_nr; chg_idx++) { @@ -388,13 +393,17 @@ int __init e820__update_table(struct e820_table *ta= ble) * 1=3Dusable, 2,3,4,4+=3Dunusable) */ current_type =3D 0; + current_crypto =3D 1; for (i =3D 0; i < overlap_entries; i++) { + current_crypto =3D current_crypto && 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 - l= ast_addr; /* Move forward only if the new size was non-zero: */ @@ -406,9 +415,12 @@ int __init e820__update_table(struct e820_table *tab= le) 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 @@ -459,14 +471,20 @@ static int __init append_e820_table(struct boot_e82= 0_entry *entries, u32 nr_entr return __append_e820_table(entries, nr_entries); } =20 +/* + * Update a memory range. + * + * If old_type and new_type are the same then ignore the types and + * just change crypto_capable. + */ static u64 __init -__e820__range_update(struct e820_table *table, u64 start, u64 size, enum= e820_type old_type, enum e820_type new_type) +__e820__range_update(struct e820_table *table, u64 start, u64 size, enum= e820_type old_type, enum e820_type new_type, u8 crypto_capable) { u64 end; unsigned int i; u64 real_updated_size =3D 0; =20 - BUG_ON(old_type =3D=3D new_type); + bool update_crypto =3D new_type =3D=3D old_type; =20 if (size > (ULLONG_MAX - start)) size =3D ULLONG_MAX - start; @@ -476,6 +494,8 @@ __e820__range_update(struct e820_table *table, u64 st= art, u64 size, enum e820_ty e820_print_type(old_type); pr_cont(" =3D=3D> "); e820_print_type(new_type); + if (crypto_capable) + pr_cont("; crypto-capable"); pr_cont("\n"); =20 for (i =3D 0; i < table->nr_entries; i++) { @@ -483,22 +503,27 @@ __e820__range_update(struct e820_table *table, u64 = start, u64 size, enum e820_ty u64 final_start, final_end; u64 entry_end; =20 - if (entry->type !=3D old_type) + if (entry->type !=3D old_type && !update_crypto) continue; =20 + if (update_crypto) + new_type =3D entry->type; + entry_end =3D entry->addr + entry->size; =20 /* Completely covered by new range? */ if (entry->addr >=3D start && entry_end <=3D end) { entry->type =3D new_type; + entry->crypto_capable =3D crypto_capable; real_updated_size +=3D entry->size; continue; } =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); + __e820__range_add(table, start, size, new_type, crypto_capable); + __e820__range_add(table, end, entry_end - end, + entry->type, entry->crypto_capable); entry->size =3D start - entry->addr; real_updated_size +=3D size; continue; @@ -510,7 +535,8 @@ __e820__range_update(struct e820_table *table, u64 st= art, u64 size, enum e820_ty if (final_start >=3D final_end) continue; =20 - __e820__range_add(table, final_start, final_end - final_start, new_typ= e); + __e820__range_add(table, final_start, final_end - final_start, + new_type, crypto_capable); =20 real_updated_size +=3D final_end - final_start; =20 @@ -527,14 +553,19 @@ __e820__range_update(struct e820_table *table, u64 = start, u64 size, enum e820_ty return real_updated_size; } =20 +u64 __init e820__range_mark_as_crypto_capable(u64 start, u64 size) +{ + return __e820__range_update(e820_table, start, size, 0, 0, true); +} + u64 __init e820__range_update(u64 start, u64 size, enum e820_type old_ty= pe, enum e820_type new_type) { - return __e820__range_update(e820_table, start, size, old_type, new_type= ); + return __e820__range_update(e820_table, start, size, old_type, new_type= , false); } =20 static u64 __init e820__range_update_kexec(u64 start, u64 size, enum e82= 0_type old_type, enum e820_type new_type) { - return __e820__range_update(e820_table_kexec, start, size, old_type, ne= w_type); + return __e820__range_update(e820_table_kexec, start, size, old_type, ne= w_type, false); } =20 /* Remove a range of memory from the E820 table: */ @@ -572,7 +603,9 @@ u64 __init e820__range_remove(u64 start, u64 size, en= um e820_type old_type, bool =20 /* Is the new range completely covered? */ if (entry->addr < start && entry_end > end) { - e820__range_add(end, entry_end - end, entry->type); + __e820__range_add(e820_table, end, entry_end - end, + entry->type, entry->crypto_capable); + entry->size =3D start - entry->addr; real_removed_size +=3D size; continue; @@ -1322,6 +1355,8 @@ void __init e820__memblock_setup(void) continue; =20 memblock_add(entry->addr, entry->size); + if (entry->crypto_capable) + memblock_mark_crypto_capable(entry->addr, entry->size); } =20 /* Throw away partial pages: */ --=20 2.30.2