All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin Fernandez <martin.fernandez@eclypsium.com>
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 <martin.fernandez@eclypsium.com>
Subject: [PATCH v9 7/9] x86/e820: Add unit tests for e820_range_* functions
Date: Mon,  4 Jul 2022 10:58:31 -0300	[thread overview]
Message-ID: <20220704135833.1496303-8-martin.fernandez@eclypsium.com> (raw)
In-Reply-To: <20220704135833.1496303-1-martin.fernandez@eclypsium.com>

Add KUnit tests for the e820_range_* functions.

Signed-off-by: Martin Fernandez <martin.fernandez@eclypsium.com>
---
 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 <kunit/test.h>
+
+#include <asm/e820/api.h>
+#include <asm/setup.h>
+
+#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);
-- 
2.30.2


  parent reply	other threads:[~2022-07-04 14:00 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-04 13:58 [PATCH v9 0/9] x86: Show in sysfs if a memory node is able to do encryption Martin Fernandez
2022-07-04 13:58 ` [PATCH v9 1/9] mm/memblock: Tag memblocks with crypto capabilities Martin Fernandez
2022-07-04 13:58 ` [PATCH v9 2/9] mm/mmzone: Tag pg_data_t " Martin Fernandez
2022-10-07 15:53   ` Kirill A. Shutemov
2022-10-11 13:28     ` Martin Fernandez
2022-10-11 15:27       ` Kirill A. Shutemov
2022-07-04 13:58 ` [PATCH v9 3/9] x86/e820: Add infrastructure to refactor e820__range_{update,remove} Martin Fernandez
2022-07-04 13:58 ` [PATCH v9 4/9] x86/e820: Refactor __e820__range_update Martin Fernandez
2022-07-04 13:58 ` [PATCH v9 5/9] x86/e820: Refactor e820__range_remove Martin Fernandez
2022-07-04 13:58 ` [PATCH v9 6/9] x86/e820: Tag e820_entry with crypto capabilities Martin Fernandez
2022-07-04 13:58 ` Martin Fernandez [this message]
2022-07-05  2:04   ` [PATCH v9 7/9] x86/e820: Add unit tests for e820_range_* functions David Gow
2022-07-05  2:04     ` David Gow
2022-07-05 17:24     ` Martin Fernandez
2022-07-04 13:58 ` [PATCH v9 8/9] x86/efi: Mark e820_entries as crypto capable from EFI memmap Martin Fernandez
2022-07-04 13:58 ` [PATCH v9 9/9] drivers/node: Show in sysfs node's crypto capabilities Martin Fernandez
2022-07-04 14:34   ` Greg KH
2022-07-05 17:35     ` Martin Fernandez
2022-07-06  6:38       ` Greg KH
2022-10-13 19:48 ` [PATCH v9 0/9] x86: Show in sysfs if a memory node is able to do encryption Borislav Petkov
2022-10-13 21:00   ` Martin Fernandez
2022-10-27  8:57     ` Borislav Petkov
2022-10-27 15:21       ` Dave Hansen
2022-10-27 15:33         ` Borislav Petkov
2022-10-14  0:24   ` Dave Hansen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220704135833.1496303-8-martin.fernandez@eclypsium.com \
    --to=martin.fernandez@eclypsium.com \
    --cc=akpm@linux-foundation.org \
    --cc=alex.bazhaniuk@eclypsium.com \
    --cc=alison.schofield@intel.com \
    --cc=andy@infradead.org \
    --cc=ardb@kernel.org \
    --cc=bp@alien8.de \
    --cc=daniel.gutson@eclypsium.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=dvhart@infradead.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=hpa@zytor.com \
    --cc=hughsient@gmail.com \
    --cc=keescook@chromium.org \
    --cc=kunit-dev@googlegroups.com \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mingo@redhat.com \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=rafael@kernel.org \
    --cc=rppt@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.