From patchwork Mon Jul 4 13:58: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: 587942 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 BAE08CCA479 for ; Mon, 4 Jul 2022 13:59:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234597AbiGDN7C (ORCPT ); Mon, 4 Jul 2022 09:59:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233278AbiGDN6z (ORCPT ); Mon, 4 Jul 2022 09:58:55 -0400 Received: from mail-vs1-xe30.google.com (mail-vs1-xe30.google.com [IPv6:2607:f8b0:4864:20::e30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C314A7647 for ; Mon, 4 Jul 2022 06:58:52 -0700 (PDT) Received: by mail-vs1-xe30.google.com with SMTP id z66so9094869vsb.3 for ; Mon, 04 Jul 2022 06:58:52 -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=erdqpZYLja6xDuoUNWXMJOEwQp9qkWbhvYqoJ4co3Os=; b=V55waJR1QuKM8kC/rFEuxJwFmNLdmPKax7+zW9/siL7Mj36HUtopitwFYdMlAFbeEs rJWfeTLZaAEsZjfihwA9mJ7xH9DS6H9oWLlqTnMtLoS/+23JMDhQ3IeR7ap5oaFtTKxK Y+I83AZEsaJ4Ay6DnahMYHrQ3Gb04a7ON/+7oqwxrHjP8z+A6KzcYQNYXByQHkOWPqg2 FMPJkOHXrsJy7Eom5pARQ4bPJtkhaMhDPV5VhmeydbYuyBO61FHK10EdQ0vYkxE/OsLv t0rVB5AnOjfnQIbOlZIGo+FUsNZbVLhmEYJK9HYBt89yoXq1Mt6q8egiAwbnhj3Hep95 8kTw== 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=erdqpZYLja6xDuoUNWXMJOEwQp9qkWbhvYqoJ4co3Os=; b=0RgFkDpzObCPZ5PVhGjPo6FJjJ0XAhjkCIrgq8iej6tcVixUOzBSDcyr6uW64s6kkw socj24ScJfKVTtJgmMesZ2Wy1G8N6lFY2q+NDJDKpfXrIbQN3M8QToJ0iYMDWkkdyAMq pXlnNlM2IqohapT/X0wp96N0/qOMT8OMo/HGRnoepdtELEUUBgOfr64KeY+zoBHLkLKr TmT4HgB1bsK7YlIa7+X9tjNSKZ6U1RF7VoSInOxFF4yuido1T3Hnb556bFai5unSEWlt f7NVVFqrrsHYsr41BIeG8sNskT9NqP2tKk7COXUoPT/tBvKB65IrrC2bNdNOm45VxG5a 1POA== X-Gm-Message-State: AJIora82CuqmEfuFldOv2VitFDKWmvYmIod+RGbJBeIoWQOb/Ar0XVAL Q08mTh1T8CO1K7WnQDKRceOAyA== X-Google-Smtp-Source: AGRyM1uu2u3rbg5Giv2gmMbrQfmLY/m5Z5qJo0bY5VChxGRJJIApXm7e/0jrs7sHJbYJu65GFpqcqw== X-Received: by 2002:a67:43c4:0:b0:354:49cf:f663 with SMTP id q187-20020a6743c4000000b0035449cff663mr16345113vsa.38.1656943132140; Mon, 04 Jul 2022 06:58:52 -0700 (PDT) Received: from localhost ([181.97.174.128]) by smtp.gmail.com with ESMTPSA id v16-20020a056102303000b0035609fbb1a9sm3567826vsa.1.2022.07.04.06.58.47 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 04 Jul 2022 06:58:51 -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, kunit-dev@googlegroups.com, linux-kselftest@vger.kernel.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 v9 1/9] mm/memblock: Tag memblocks with crypto capabilities Date: Mon, 4 Jul 2022 10:58:25 -0300 Message-Id: <20220704135833.1496303-2-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220704135833.1496303-1-martin.fernandez@eclypsium.com> References: <20220704135833.1496303-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@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..d6399835b155 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 @nid 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 crypto_capables > 0 && 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 Jul 4 13:58:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Fernandez X-Patchwork-Id: 587941 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 35329C43334 for ; Mon, 4 Jul 2022 13:59:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234810AbiGDN71 (ORCPT ); Mon, 4 Jul 2022 09:59:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234525AbiGDN7L (ORCPT ); Mon, 4 Jul 2022 09:59:11 -0400 Received: from mail-vs1-xe36.google.com (mail-vs1-xe36.google.com [IPv6:2607:f8b0:4864:20::e36]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 74B73DF42 for ; Mon, 4 Jul 2022 06:59:07 -0700 (PDT) Received: by mail-vs1-xe36.google.com with SMTP id z66so9095446vsb.3 for ; Mon, 04 Jul 2022 06:59:07 -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=bzJenq/qxXZmxxl1Ksk6HJARtm3Ihl+B/CevCTs1JBk=; b=X2BYzcnRkUF9v6ZNqHr/J99bVmc6++VMWdfFNw36eEddAOQr4vRkHVyotRUK42q4bW 5fK+j8JbnkgPutr6FLwuTu4IhOuvnYXJK9KhSRIE074BY3hJIA/dSCQ0ZPokoYKRq9bG K2w65R5Pr8SdwAtf0y4ushiB/Qi4Gt/KoqyOQ6V7U/lK23q17WXGXZaYWD0URiM/D1lA KKLDW8cek6v4qnaFNCRC1ANZEcL0kVN0mz+4wBzKyMnZ1sxdBX07rM3AMrM19cVrRaxe 8WAHIANoBJg3qczWKPs9+w29IEuY+hvYAIDCH3/4EoTNTkMSYKR8Y4WjU1ffGUNI3QKy Aebg== 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=bzJenq/qxXZmxxl1Ksk6HJARtm3Ihl+B/CevCTs1JBk=; b=ToO5/ai2t368HmqjzObap9u6eXbO8dtWT7xZbFm+iH/RpYHMPJ3tHbxnNuncUNGNUg V32GAo785nxJXPus3cZMqbiTA37t6NcRPAIuhfl9DxTj8u3gvKpvo6atzdmjd68BV2DX CLESGF+037YwfLSJYhr2wDnj8s8jmc3tBzuDKOEeCd60jR0lNjO9KObHc2Si7eKO4vRI 37bkVonGlggknYY/TkKVfzHJWQzds5nYRkiGKWygKzP5GQXpoX05I7LaxA8HaJwkQdn1 caruskfOcTW15nmu0Eu0s7QpwisL9N7S23468cpjwFFou78rm2GZSxJ8NqPvsKg95oHF lXBg== X-Gm-Message-State: AJIora8c39adOJUMK1WstHAja9JvbLKFV9AL1Gx0HJm/b589mJ8hSdPL i+FQ61JglzdVTjpfQKFFsnVIyw== X-Google-Smtp-Source: AGRyM1sww168oavtBsM/BaefGrhT8xpWzlBWhslMAxgTNmfgjWhNTVANPgnpuFJruMWEoqpoYBxi6Q== X-Received: by 2002:a67:f74c:0:b0:354:5c29:aad7 with SMTP id w12-20020a67f74c000000b003545c29aad7mr14534161vso.40.1656943146559; Mon, 04 Jul 2022 06:59:06 -0700 (PDT) Received: from localhost ([181.97.174.128]) by smtp.gmail.com with ESMTPSA id j68-20020a1fa047000000b0036cefdde1cbsm4173891vke.10.2022.07.04.06.59.02 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 04 Jul 2022 06:59:06 -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, kunit-dev@googlegroups.com, linux-kselftest@vger.kernel.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 v9 3/9] x86/e820: Add infrastructure to refactor e820__range_{update,remove} Date: Mon, 4 Jul 2022 10:58:27 -0300 Message-Id: <20220704135833.1496303-4-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220704135833.1496303-1-martin.fernandez@eclypsium.com> References: <20220704135833.1496303-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@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 -------------------------------------------------- Changes from v7 to v8: (Some) Callbacks of e820_entry_updater can now be NULL to avoid defining empty functions Remove kerneldocs in favor of plain comments just to explain what the functions do. --- arch/x86/kernel/e820.c | 127 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index f267205f2d5a..e0fa3ab755a5 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -459,6 +459,133 @@ 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. Can be set to NULL to avoid empty functions. + * @new: Create new entry in the table with information gathered from + * @original and @data. Can be set to NULL to avoid empty functions. + * + * 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); +}; + +/* + * 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. + */ +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; + } + if (updater->new != NULL) + /* 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; +} + +/* + * Update the table @table in [@start, @start + @size) doing the + * actions given in @updater. + */ +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; + if (updater->update != NULL) + updater->update(entry, data); + /* Entry completely covers range */ + } else if (start > entry->addr && end < entry_end) { + /* Resize current entry */ + entry->size = start - entry->addr; + + if (updater->new != NULL) + /* 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 += 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 Jul 4 13:58:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Fernandez X-Patchwork-Id: 587940 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 9C368CCA479 for ; Mon, 4 Jul 2022 13:59:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234525AbiGDN7r (ORCPT ); Mon, 4 Jul 2022 09:59:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37994 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234831AbiGDN73 (ORCPT ); Mon, 4 Jul 2022 09:59:29 -0400 Received: from mail-vk1-xa36.google.com (mail-vk1-xa36.google.com [IPv6:2607:f8b0:4864:20::a36]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CE0AAE092 for ; Mon, 4 Jul 2022 06:59:21 -0700 (PDT) Received: by mail-vk1-xa36.google.com with SMTP id r1so4472842vke.8 for ; Mon, 04 Jul 2022 06:59:21 -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=rnE47zkhbqWUJCOF0oFEixfkiu1ztx/JWB/tGri5YXI=; b=LPaDJYKM/DGiUp92Hh+jPbmInAsxrzuU0gaRNet6zG9cOie6oZ549PRb7KfPsYEAE+ HT+Z8VnJYmxAZDDADvU5oJsQTb96tcokrDSY9ESIQ/Avq4F0dqKDdRdiVdhzH5+fc+su fTZHP+JiqUbKTr5LPoZ3FJyLmgK/NTHxa0HmS1z60R9vUPkQ6YFr8wjBwHBpDiB4ndAi +oWLWmAKK3VzUR0A5KgO+mouqtrfvhrJf2JcoZdlBIohxQoLcA6EXMSTgVkgDl+MuMRv 00ZdBkTssQWwSgp7WN00hdh5KoWXbc4eMznXdDuJk4B/+n7DH9HCAl9gWwxm76WIA8a7 XkLg== 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=rnE47zkhbqWUJCOF0oFEixfkiu1ztx/JWB/tGri5YXI=; b=0mRPNSaYTJFLUxLUyDa65U331c9BNI+yYkWlXuKWnFoQ8UjyrEiCBvR38B/LLuYklT EEH7XoGVW3scdRTW1bLT/lfONAypwrRp6Tu0WvsvDuobnKkapKTPxqTJfrhrMqwfiJmX 3eM3UP5J33p3YjCZHNCDIOa4UHrWBotcA0FipPtCFB+9RblwOOGLEGt6GTTbGIPxqGV3 CTUQnb0QcjCcQoJzzKV2E+BUGnb08PpqZOahXI6k4v94Iuu1/T132WIIZzYTlfeVeQt1 5o+FJMxlvHMywHrLJs2EdJbqbgwnpSsBIsu3I08PFhMLC8PcshvxujvD7ag2Zsh9cmTd i7Sw== X-Gm-Message-State: AJIora9Nmcf9gfChl5JC3qkbVld4fV2LPykF+Fovv+DTeYNjAYdUIfy/ NDx4iAPRTdpfRXM59zxHRibtcw== X-Google-Smtp-Source: AGRyM1uhvKX9DY0lHDCjtBY+5BrycH2Gr0rJb29k0daor6bM+GZnlj9mVlr6FF1AhkwgIQkJl3l0dQ== X-Received: by 2002:a05:6122:1485:b0:36c:c60b:877f with SMTP id z5-20020a056122148500b0036cc60b877fmr17367399vkp.4.1656943160742; Mon, 04 Jul 2022 06:59:20 -0700 (PDT) Received: from localhost ([181.97.174.128]) by smtp.gmail.com with ESMTPSA id w1-20020ab055c1000000b0037c965ac47fsm4564520uaa.31.2022.07.04.06.59.15 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 04 Jul 2022 06:59:20 -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, kunit-dev@googlegroups.com, linux-kselftest@vger.kernel.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 v9 5/9] x86/e820: Refactor e820__range_remove Date: Mon, 4 Jul 2022 10:58:29 -0300 Message-Id: <20220704135833.1496303-6-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220704135833.1496303-1-martin.fernandez@eclypsium.com> References: <20220704135833.1496303-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@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 | 94 ++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 53 deletions(-) diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 36a22c0a2199..0e5aa13ebdb8 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -669,66 +669,54 @@ 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; - - if (check_type && entry->type != old_type) - continue; +/* + * Type helper for the e820_entry_updater callbacks. + */ +struct e820_remover_data { + enum e820_type old_type; + bool check_type; +}; - entry_end = entry->addr + entry->size; +static bool __init remover__should_update(const struct e820_entry *entry, + const void *data) +{ + const struct e820_remover_data *remover_data = data; - /* Completely covered? */ - if (entry->addr >= start && entry_end <= end) { - real_removed_size += entry->size; - memset(entry, 0, sizeof(*entry)); - continue; - } + return !remover_data->check_type || + entry->type == remover_data->old_type; +} - /* 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__update(struct e820_entry *entry, const void *data) +{ + memset(entry, 0, sizeof(*entry)); +} - /* Partially covered: */ - final_start = max(start, entry->addr); - final_end = min(end, entry_end); - if (final_start >= final_end) - continue; +/* + * Remove [@start, @start + @size) from e820_table. If @check_type is + * true remove only entries with type @old_type. + */ +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 = NULL + }; - 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 Jul 4 13:58:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Fernandez X-Patchwork-Id: 587939 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 57F16C43334 for ; Mon, 4 Jul 2022 14:00:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234488AbiGDOAO (ORCPT ); Mon, 4 Jul 2022 10:00:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234780AbiGDN7m (ORCPT ); Mon, 4 Jul 2022 09:59:42 -0400 Received: from mail-vs1-xe2d.google.com (mail-vs1-xe2d.google.com [IPv6:2607:f8b0:4864:20::e2d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DEFD3101F0 for ; Mon, 4 Jul 2022 06:59:35 -0700 (PDT) Received: by mail-vs1-xe2d.google.com with SMTP id 189so9109742vsh.2 for ; Mon, 04 Jul 2022 06:59:35 -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=z0DiM2QAFWfRCxyX4K2DXOUSOAXhJvDrH/Deu05TYDY=; b=cMagWlDmtdm3o1f6Pp61sL3GddrPHHQmPJWDvSTOuRfLNvZ4cPGhTJfzZcNjMxrfjr sEbPLuO9RK2jvBXKZnS9xayzZJumnLdPqvIynQ9cWked5s3vnTxQdeo28d4/wfb8C+zL +VqvZGqgvnIkqw2lFDv9JbvIbcCYWy3hB/iNAJspkY9a7o4Q1VoIgfVn/623KrxQ6I8u eBXrG3RP91GB1gMw5zXSyVmi+899r4kspuuZqoR6lSx57tZplo1sbF5vEuTQ+y2qVoe1 Uleb7KRX5XfIrNZYJg5CDMbrmtp+/rvl0vg6DLjHMniyMb0Rvs4lD12kZGILIPOpk4sW U/4Q== 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=z0DiM2QAFWfRCxyX4K2DXOUSOAXhJvDrH/Deu05TYDY=; b=GcYevQbbYveNw4eygmA6Glw+p3B+YEs8F/iGSMpcDzbIiFTalzKRDXaIjEJEMUeFB/ KtJDYT1aQSCmi4TMKhtz2rwFz7SUg1DUDU03DB6h49E7lkkJrY+D+NZFdOxH/39ckQQD HReqtUJv1PDnC4GVEAfU6sQ4gOW8Onxpz8SeJ0v/8uNzhdTsRl9m7CbnWG4jniLpOGu/ mKTTpfQ3OtiGxZGf1Qv9uQFehyWRDXmDpw7RY08H938L+NBhdbZdGwDqm6YS7afGZZ/s n96DwDb6D8yuw3AE8EpMB7GEt4VWtVU3M45kyfshxiqpf3ST+wAKLBlIvXUxxcVJXHGe ZqDw== X-Gm-Message-State: AJIora91BIrfu5Uij5Du48TGx7KAje55TZF7LwpHsvUQJ5IWAgvMcOwT S30d5RkOAGs5gqgXKbRORVpgOptAoR0ZZQ== X-Google-Smtp-Source: AGRyM1sE6muSOvx2k+xe3UnPJZ2WVCBPj7qW4PpsjOJJKZzXCsbFp4uxqOIHZ9lHyDxUhrjpJWshnQ== X-Received: by 2002:a67:eb0b:0:b0:354:5c77:775c with SMTP id a11-20020a67eb0b000000b003545c77775cmr17327338vso.46.1656943175020; Mon, 04 Jul 2022 06:59:35 -0700 (PDT) Received: from localhost ([181.97.174.128]) by smtp.gmail.com with ESMTPSA id x24-20020ab036f8000000b0038296f80d22sm724438uau.8.2022.07.04.06.59.29 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 04 Jul 2022 06:59:34 -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, kunit-dev@googlegroups.com, linux-kselftest@vger.kernel.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 v9 7/9] x86/e820: Add unit tests for e820_range_* functions Date: Mon, 4 Jul 2022 10:58:31 -0300 Message-Id: <20220704135833.1496303-8-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220704135833.1496303-1-martin.fernandez@eclypsium.com> References: <20220704135833.1496303-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Add KUnit tests for the e820_range_* functions. Signed-off-by: Martin Fernandez --- arch/x86/Kconfig.debug | 10 ++ arch/x86/kernel/e820.c | 5 + arch/x86/kernel/e820_test.c | 249 ++++++++++++++++++++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 arch/x86/kernel/e820_test.c diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index d872a7522e55..b5040d345fb4 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -225,6 +225,16 @@ config PUNIT_ATOM_DEBUG The current power state can be read from /sys/kernel/debug/punit_atom/dev_power_state +config E820_KUNIT_TEST + tristate "Tests for E820" if !KUNIT_ALL_TESTS + depends on KUNIT=y + default KUNIT_ALL_TESTS + help + This option enables unit tests for the e820.c code. It + should be enabled only in development environments. + + If unsure, say N. + choice prompt "Choose kernel unwinder" default UNWINDER_ORC if X86_64 diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index dade59758b9f..a6ced3e306dd 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -1546,3 +1546,8 @@ void __init e820__memblock_setup(void) memblock_dump_all(); } + +#ifdef CONFIG_E820_KUNIT_TEST +/* Let e820_test have access the static functions in this file */ +#include "e820_test.c" +#endif diff --git a/arch/x86/kernel/e820_test.c b/arch/x86/kernel/e820_test.c new file mode 100644 index 000000000000..6b28ea131380 --- /dev/null +++ b/arch/x86/kernel/e820_test.c @@ -0,0 +1,249 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include + +#include +#include + +#define KUNIT_EXPECT_E820_ENTRY_EQ(_test, _entry, _addr, _size, _type, \ + _crypto_capable) \ + do { \ + KUNIT_EXPECT_EQ((_test), (_entry).addr, (_addr)); \ + KUNIT_EXPECT_EQ((_test), (_entry).size, (_size)); \ + KUNIT_EXPECT_EQ((_test), (_entry).type, (_type)); \ + KUNIT_EXPECT_EQ((_test), (_entry).crypto_capable, \ + (_crypto_capable)); \ + } while (0) + +struct e820_table test_table __initdata; + +static void __init test_e820_range_add(struct kunit *test) +{ + u32 full = ARRAY_SIZE(test_table.entries); + /* Add last entry. */ + test_table.nr_entries = full - 1; + __e820__range_add(&test_table, 0, 15, 0, 0); + KUNIT_EXPECT_EQ(test, test_table.nr_entries, full); + /* Skip new entry when full. */ + __e820__range_add(&test_table, 0, 15, 0, 0); + KUNIT_EXPECT_EQ(test, test_table.nr_entries, full); +} + +static void __init test_e820_range_update(struct kunit *test) +{ + u64 entry_size = 15; + u64 updated_size = 0; + /* Initialize table */ + test_table.nr_entries = 0; + __e820__range_add(&test_table, 0, entry_size, E820_TYPE_RAM, + E820_NOT_CRYPTO_CAPABLE); + __e820__range_add(&test_table, entry_size, entry_size, E820_TYPE_RAM, + E820_NOT_CRYPTO_CAPABLE); + __e820__range_add(&test_table, entry_size * 2, entry_size, + E820_TYPE_ACPI, E820_NOT_CRYPTO_CAPABLE); + + updated_size = __e820__range_update(&test_table, 0, entry_size * 2, + E820_TYPE_RAM, E820_TYPE_RESERVED); + + /* The first 2 regions were updated */ + KUNIT_EXPECT_EQ(test, updated_size, entry_size * 2); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[0], 0, entry_size, + E820_TYPE_RESERVED, E820_NOT_CRYPTO_CAPABLE); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[1], entry_size, + entry_size, E820_TYPE_RESERVED, + E820_NOT_CRYPTO_CAPABLE); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[2], entry_size * 2, + entry_size, E820_TYPE_ACPI, + E820_NOT_CRYPTO_CAPABLE); + + updated_size = __e820__range_update(&test_table, 0, entry_size * 3, + E820_TYPE_RESERVED, E820_TYPE_RAM); + + /* + * Only the first 2 regions were updated, + * since E820_TYPE_ACPI > E820_TYPE_RESERVED + */ + KUNIT_EXPECT_EQ(test, updated_size, entry_size * 2); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[0], 0, entry_size, + E820_TYPE_RAM, E820_NOT_CRYPTO_CAPABLE); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[1], entry_size, + entry_size, E820_TYPE_RAM, + E820_NOT_CRYPTO_CAPABLE); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[2], entry_size * 2, + entry_size, E820_TYPE_ACPI, + E820_NOT_CRYPTO_CAPABLE); +} + +static void __init test_e820_range_remove(struct kunit *test) +{ + u64 entry_size = 15; + u64 removed_size = 0; + + struct e820_entry_updater updater = { .should_update = + remover__should_update, + .update = remover__update, + .new = NULL }; + + struct e820_remover_data data = { .check_type = true, + .old_type = E820_TYPE_RAM }; + + /* Initialize table */ + test_table.nr_entries = 0; + __e820__range_add(&test_table, 0, entry_size, E820_TYPE_RAM, + E820_NOT_CRYPTO_CAPABLE); + __e820__range_add(&test_table, entry_size, entry_size, E820_TYPE_RAM, + E820_NOT_CRYPTO_CAPABLE); + __e820__range_add(&test_table, entry_size * 2, entry_size, + E820_TYPE_ACPI, E820_NOT_CRYPTO_CAPABLE); + + /* + * Need to use __e820__handle_range_update because + * e820__range_remove doesn't ask for the table + */ + removed_size = __e820__handle_range_update(&test_table, + 0, entry_size * 2, + &updater, &data); + + /* The first two regions were removed */ + KUNIT_EXPECT_EQ(test, removed_size, entry_size * 2); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[0], 0, 0, 0, 0); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[1], 0, 0, 0, 0); + + removed_size = __e820__handle_range_update(&test_table, + 0, entry_size * 3, + &updater, &data); + + /* Nothing was removed, since nothing matched the target type */ + KUNIT_EXPECT_EQ(test, removed_size, 0); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[0], 0, 0, 0, 0); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[1], 0, 0, 0, 0); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[2], entry_size * 2, + entry_size, E820_TYPE_ACPI, + E820_NOT_CRYPTO_CAPABLE); +} + +static void __init test_e820_range_crypto_update(struct kunit *test) +{ + u64 entry_size = 15; + u64 updated_size = 0; + /* Initialize table */ + test_table.nr_entries = 0; + __e820__range_add(&test_table, 0, entry_size, E820_TYPE_RAM, + E820_CRYPTO_CAPABLE); + __e820__range_add(&test_table, entry_size, entry_size, E820_TYPE_RAM, + E820_NOT_CRYPTO_CAPABLE); + __e820__range_add(&test_table, entry_size * 2, entry_size, + E820_TYPE_RAM, E820_CRYPTO_CAPABLE); + + updated_size = __e820__range_update_crypto(&test_table, + 0, entry_size * 3, + E820_CRYPTO_CAPABLE); + + /* Only the region in the middle was updated */ + KUNIT_EXPECT_EQ(test, updated_size, entry_size); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[0], 0, entry_size, + E820_TYPE_RAM, E820_CRYPTO_CAPABLE); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[1], entry_size, + entry_size, E820_TYPE_RAM, + E820_CRYPTO_CAPABLE); + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[2], entry_size * 2, + entry_size, E820_TYPE_RAM, + E820_CRYPTO_CAPABLE); +} + +static void __init test_e820_handle_range_update_intersection(struct kunit *test) +{ + struct e820_entry_updater updater = { + .should_update = type_updater__should_update, + .update = type_updater__update, + .new = type_updater__new + }; + + struct e820_type_updater_data data = { .old_type = E820_TYPE_RAM, + .new_type = E820_TYPE_RESERVED }; + + u64 entry_size = 15; + u64 intersection_size = 2; + u64 updated_size = 0; + /* Initialize table */ + test_table.nr_entries = 0; + __e820__range_add(&test_table, 0, entry_size, E820_TYPE_RAM, + E820_NOT_CRYPTO_CAPABLE); + + updated_size = + __e820__handle_range_update(&test_table, 0, + entry_size - intersection_size, + &updater, &data); + + KUNIT_EXPECT_EQ(test, updated_size, entry_size - intersection_size); + + /* There is a new entry */ + KUNIT_EXPECT_EQ(test, test_table.nr_entries, intersection_size); + + /* The original entry now is moved */ + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[0], + entry_size - intersection_size, + intersection_size, E820_TYPE_RAM, + E820_NOT_CRYPTO_CAPABLE); + + /* The new entry has the correct values */ + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[1], 0, + entry_size - intersection_size, + E820_TYPE_RESERVED, E820_NOT_CRYPTO_CAPABLE); +} + +static void __init test_e820_handle_range_update_inside(struct kunit *test) +{ + struct e820_entry_updater updater = { + .should_update = type_updater__should_update, + .update = type_updater__update, + .new = type_updater__new + }; + + struct e820_type_updater_data data = { .old_type = E820_TYPE_RAM, + .new_type = E820_TYPE_RESERVED }; + + u64 entry_size = 15; + u64 updated_size = 0; + /* Initialize table */ + test_table.nr_entries = 0; + __e820__range_add(&test_table, 0, entry_size, E820_TYPE_RAM, + E820_NOT_CRYPTO_CAPABLE); + + updated_size = __e820__handle_range_update(&test_table, 5, + entry_size - 10, + &updater, &data); + + KUNIT_EXPECT_EQ(test, updated_size, entry_size - 10); + + /* There are two new entrie */ + KUNIT_EXPECT_EQ(test, test_table.nr_entries, 3); + + /* The original entry now shrunk */ + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[0], 0, 5, + E820_TYPE_RAM, E820_NOT_CRYPTO_CAPABLE); + + /* The new entries have the correct values */ + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[1], 5, + entry_size - 10, E820_TYPE_RESERVED, + E820_NOT_CRYPTO_CAPABLE); + /* Left over of the original region */ + KUNIT_EXPECT_E820_ENTRY_EQ(test, test_table.entries[2], entry_size - 5, + 5, E820_TYPE_RAM, E820_NOT_CRYPTO_CAPABLE); +} + +static struct kunit_case e820_test_cases[] __initdata = { + KUNIT_CASE(test_e820_range_add), + KUNIT_CASE(test_e820_range_update), + KUNIT_CASE(test_e820_range_remove), + KUNIT_CASE(test_e820_range_crypto_update), + KUNIT_CASE(test_e820_handle_range_update_intersection), + KUNIT_CASE(test_e820_handle_range_update_inside), + {} +}; + +static struct kunit_suite e820_test_suite __initdata = { + .name = "e820", + .test_cases = e820_test_cases, +}; + +kunit_test_init_section_suite(e820_test_suite); From patchwork Mon Jul 4 13:58:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Fernandez X-Patchwork-Id: 587938 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 1A218C43334 for ; Mon, 4 Jul 2022 14:00:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234499AbiGDOAa (ORCPT ); Mon, 4 Jul 2022 10:00:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38146 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234842AbiGDOAB (ORCPT ); Mon, 4 Jul 2022 10:00:01 -0400 Received: from mail-vs1-xe32.google.com (mail-vs1-xe32.google.com [IPv6:2607:f8b0:4864:20::e32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EEABDE03C for ; Mon, 4 Jul 2022 06:59:47 -0700 (PDT) Received: by mail-vs1-xe32.google.com with SMTP id j6so9139908vsi.0 for ; Mon, 04 Jul 2022 06:59:47 -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=hiQZs7RQJ57Y3iMEvjKPq7apwG47z8xfODnJPhnyEtM=; b=h0cx2J376VdMDKbdnNSudAZQFU5bNAb+af1nsukIB0ohm1yOAPCujoxEhD9RXdrsTN 59gWNY7oIZmpnuoyFxH0Lfsl2dJloyzrktCOwSAhx/pcUBpqAhwobasrepx8jaNSG5IB +3V+Cz/MOtaMXMEN5TEaTQPabi0feo2LWbZUM09F5pJcBvlR9ydj4wefZ1gUCoZ/Kj3d 6Zk5liSBxCrOnBdnuOagWCvacvfTLNkQFDUyGttjpU3agSg/uS+wBYUlyl0jI+GWDtdB 7y3rJJBNyXJ0bQlJkj2s+b4F6h4T+dammjL6tWPz3wX8lhSw7YKSuZK8HHmrFpWUNLAO TyUQ== 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=hiQZs7RQJ57Y3iMEvjKPq7apwG47z8xfODnJPhnyEtM=; b=NBklmd4uPFKaDj8iALJ04Dfe+sI/Rrl4mdSss0rwBLklR/yKKvdbqSzRDiNSziALhB Cey81Y+CfmVKuoIeWDB+FhVt/hrRYywGZPi49HDnCJ2hsP9QE9AyNM/5iaVn8BcQ79cs 2OgkLpV8f4bVGNB1Kvc7EHOgxW/av0/9WDzcDNbk1xfZ2jFXAZ+rwT8r07WxcwD+eqzN +oIjHImTdtTfCvnCsxUQF5WnKsjHp3szsoGN2gJei48o9Qq4oqSRCB8V3wTFkVIBBhNh xx3vEsX7128celAKmKX11dpDkfQWyz3cyPD+RuK+P3vdd2bJ5MfIaQRbUWPm/Dh2j7Yy VAvQ== X-Gm-Message-State: AJIora+2Ea+5Aku27otPAiiC4gfQGpBpc7wqWX32hyRwVBW03QCbjLef K2DXGIYZJ1cqre749kbd80f7Gw== X-Google-Smtp-Source: AGRyM1tZA+RFAUNVohbAzEyn5WDlKTAd76W0duJR+JCRJSy8RhT4D5c7wIBcLsYpIxHYYEOGInbcGg== X-Received: by 2002:a67:f142:0:b0:356:3251:e53d with SMTP id t2-20020a67f142000000b003563251e53dmr16561722vsm.40.1656943187638; Mon, 04 Jul 2022 06:59:47 -0700 (PDT) Received: from localhost ([181.97.174.128]) by smtp.gmail.com with ESMTPSA id p25-20020ab06259000000b00382b14a73afsm311704uao.30.2022.07.04.06.59.43 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 04 Jul 2022 06:59:47 -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, kunit-dev@googlegroups.com, linux-kselftest@vger.kernel.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 v9 9/9] drivers/node: Show in sysfs node's crypto capabilities Date: Mon, 4 Jul 2022 10:58:33 -0300 Message-Id: <20220704135833.1496303-10-martin.fernandez@eclypsium.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220704135833.1496303-1-martin.fernandez@eclypsium.com> References: <20220704135833.1496303-1-martin.fernandez@eclypsium.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Show in each node in sysfs if its memory is able to do be encrypted by the CPU; on EFI systems: 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/ABI/testing/sysfs-devices-node new file mode 100644 index 000000000000..0e95420bd7c5 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-devices-node @@ -0,0 +1,10 @@ +What: /sys/devices/system/node/nodeX/crypto_capable +Date: April 2022 +Contact: Martin Fernandez +Users: fwupd (https://fwupd.org) +Description: + This value is 1 if all system memory in this node is + capable of being protected with the CPU's memory + cryptographic capabilities. It is 0 otherwise. + On EFI systems the node will be marked with + EFI_MEMORY_CPU_CRYPTO. \ No newline at end of file diff --git a/drivers/base/node.c b/drivers/base/node.c index 0ac6376ef7a1..f081fa48c8e6 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); +static ssize_t crypto_capable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pglist_data *pgdat = 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[] = { &dev_attr_meminfo.attr, &dev_attr_numastat.attr, &dev_attr_distance.attr, &dev_attr_vmstat.attr, + &dev_attr_crypto_capable.attr, NULL };