linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Brendan Jackman <jackmanb@google.com>
To: jackmanb@google.com, Andy Lutomirski <luto@kernel.org>,
	 Lorenzo Stoakes <lorenzo.stoakes@oracle.com>,
	"Liam R. Howlett" <Liam.Howlett@oracle.com>,
	 Suren Baghdasaryan <surenb@google.com>,
	Michal Hocko <mhocko@suse.com>,
	 Johannes Weiner <hannes@cmpxchg.org>, Zi Yan <ziy@nvidia.com>,
	 Axel Rasmussen <axelrasmussen@google.com>,
	Yuanchu Xie <yuanchu@google.com>,
	 Roman Gushchin <roman.gushchin@linux.dev>
Cc: peterz@infradead.org, bp@alien8.de, dave.hansen@linux.intel.com,
	 mingo@redhat.com, tglx@linutronix.de, akpm@linux-foundation.org,
	 david@redhat.com, derkling@google.com, junaids@google.com,
	 linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	reijiw@google.com,  rientjes@google.com, rppt@kernel.org,
	vbabka@suse.cz, x86@kernel.org,  yosry.ahmed@linux.dev
Subject: [PATCH 21/21] mm: asi_test: smoke test for [non]sensitive page allocs
Date: Wed, 24 Sep 2025 14:59:56 +0000	[thread overview]
Message-ID: <20250924-b4-asi-page-alloc-v1-21-2d861768041f@google.com> (raw)
In-Reply-To: <20250924-b4-asi-page-alloc-v1-0-2d861768041f@google.com>

Add a simple smoke test for allocating pages of different sensitivities.

Since KUnit doesn't (yet) have infrastructure for this, add custom .init
and .exit hooks to our kunit_suite that detect WARNs by checking the
kernel's taint flags before and after running the tests.

Since ASI is disabled by default, whatever command people currently use
to run KUnit tests probably won't run these tests. Therefore add a new
.kunitconfig file for the x86 tree that explicitly enables ASI. It
should be possible to delete this again when ASI is the default.

So the most straightforward way to run this test is:

tools/testing/kunit/kunit.py run --arch=x86_64 \
	--kunitconfig=arch/x86/.kunitconfig --kernel_args asi=on

The more long-winded way, which lets you customize the kernel config,
is:

mkdir -p .kunit
cp arch/x86/.kunitconfig .kunit
tools/testing/kunit/kunit.py config --arch=x86_64
make O=.kunit menuconfig  # Or debug.config or whatever
tools/testing/kunit/kunit.py run --arch=x86_64 --kernel_args asi=on

Signed-off-by: Brendan Jackman <jackmanb@google.com>
---
 arch/x86/.kunitconfig  |   7 +++
 arch/x86/Kconfig       |   7 +++
 arch/x86/mm/Makefile   |   2 +
 arch/x86/mm/asi_test.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++
 kernel/panic.c         |   2 +
 mm/init-mm.c           |   3 +
 6 files changed, 166 insertions(+)

diff --git a/arch/x86/.kunitconfig b/arch/x86/.kunitconfig
new file mode 100644
index 0000000000000000000000000000000000000000..83219e6ecca8d2064aba71fab1f15d57161fa2e4
--- /dev/null
+++ b/arch/x86/.kunitconfig
@@ -0,0 +1,7 @@
+CONFIG_PCI=y
+CONFIG_MMU=y
+CONFIG_64BIT=y
+CONFIG_X86_64=y
+CONFIG_KUNIT=y
+CONFIG_MITIGATION_ADDRESS_SPACE_ISOLATION=y
+CONFIG_ASI_KUNIT_TESTS=y
\ No newline at end of file
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index cb874c3857cf443c6235e05bc3f070b0ea2686f0..a7b5658ecb1203458e06a0a065bcc7aa7dca8538 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2458,6 +2458,13 @@ config MITIGATION_PAGE_TABLE_ISOLATION
 
 	  See Documentation/arch/x86/pti.rst for more details.
 
+config ASI_KUNIT_TESTS
+	tristate "KUnit tests for ASI" if !KUNIT_ALL_TESTS
+	depends on MITIGATION_ADDRESS_SPACE_ISOLATION && KUNIT
+	default KUNIT_ALL_TESTS
+	help
+	  Builds the KUnit tests for ASI.
+
 config MITIGATION_RETPOLINE
 	bool "Avoid speculative indirect branches in kernel"
 	select OBJTOOL if HAVE_OBJTOOL
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 5ecbff70964f61a903ac96cec3736a7cec1221fd..7c36ec7f24ebb285fcfc010004206a57536fc990 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -58,3 +58,5 @@ obj-$(CONFIG_X86_MEM_ENCRYPT)	+= mem_encrypt.o
 obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= mem_encrypt_amd.o
 
 obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= mem_encrypt_boot.o
+
+obj-$(CONFIG_ASI_KUNIT_TESTS)	+= asi_test.o
diff --git a/arch/x86/mm/asi_test.c b/arch/x86/mm/asi_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..6076a61980ed9daea63113a30e990eb02a7b08d5
--- /dev/null
+++ b/arch/x86/mm/asi_test.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/mm_types.h>
+#include <linux/mm.h>
+#include <linux/pgtable.h>
+#include <linux/set_memory.h>
+#include <linux/sched/mm.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+
+#include <kunit/resource.h>
+#include <kunit/test.h>
+
+#include <asm/asi.h>
+
+struct free_pages_ctx {
+	unsigned int order;
+	struct list_head pages;
+};
+
+static void action_many__free_pages(void *context)
+{
+	struct free_pages_ctx *ctx = context;
+	struct page *page, *tmp;
+
+	list_for_each_entry_safe(page, tmp, &ctx->pages, lru)
+		__free_pages(page, ctx->order);
+}
+
+/*
+ * Allocate a bunch of pages with the same order and GFP flags, transparently
+ * take care of error handling and cleanup. Does this all via a single KUnit
+ * resource, i.e. has a fixed memory overhead.
+ */
+static struct free_pages_ctx *do_many_alloc_pages(struct kunit *test, gfp_t gfp,
+						unsigned int order, unsigned int count)
+{
+	struct free_pages_ctx *ctx = kunit_kzalloc(
+		test, sizeof(struct free_pages_ctx), GFP_KERNEL);
+
+	KUNIT_ASSERT_NOT_NULL(test, ctx);
+	INIT_LIST_HEAD(&ctx->pages);
+	ctx->order = order;
+
+	for (int i = 0; i < count; i++) {
+		struct page *page = alloc_pages(gfp, order);
+
+		if (!page) {
+			struct page *page, *tmp;
+
+			list_for_each_entry_safe(page, tmp, &ctx->pages, lru)
+				__free_pages(page, order);
+
+			KUNIT_FAIL_AND_ABORT(test,
+				"Failed to alloc order %d page (GFP *%pG) iter %d",
+				order, &gfp, i);
+		}
+		list_add(&page->lru, &ctx->pages);
+	}
+
+	KUNIT_ASSERT_EQ(test,
+		kunit_add_action_or_reset(test, action_many__free_pages, ctx), 0);
+	return ctx;
+}
+
+/*
+ * Do some allocations that force the allocator to change the sensitivity of
+ * some blocks.
+ */
+static void test_alloc_sensitive_nonsensitive(struct kunit *test)
+{
+	unsigned long page_majority;
+	struct free_pages_ctx *ctx;
+	gfp_t gfp = GFP_KERNEL | __GFP_THISNODE;
+	struct page *page;
+
+	if (!cpu_feature_enabled(X86_FEATURE_ASI))
+		kunit_skip(test, "ASI off. Set asi=on in kernel cmdline\n");
+
+	/* No cleanup here - assuming kthread "belongs" to this test. */
+	set_cpus_allowed_ptr(current, cpumask_of_node(numa_node_id()));
+
+	/*
+	 * First allocate more than half of the memory in the node as
+	 * nonsensitive. Assuming the memory starts out unmapped, this should
+	 * exercise the sensitive->nonsensitive flip already.
+	 */
+	page_majority = (node_present_pages(numa_node_id()) / 2) + 1;
+	ctx = do_many_alloc_pages(test, gfp, 0, page_majority);
+
+	/* Check pages are mapped */
+	list_for_each_entry(page, &ctx->pages, lru) {
+		/*
+		 * Logically it should be an EXPECT, but that would cause heavy
+		 * log spam on failure so use ASSERT for concision.
+		 */
+		KUNIT_ASSERT_FALSE(test, direct_map_sensitive(page));
+	}
+
+	/*
+	 * Now free them again and allocate the same amount as sensitive.
+	 * This will exercise the nonsensitive->sensitive flip.
+	 */
+	kunit_release_action(test, action_many__free_pages, ctx);
+	gfp |= __GFP_SENSITIVE;
+	ctx = do_many_alloc_pages(test, gfp, 0, page_majority);
+
+	/* Check pages are unmapped */
+	list_for_each_entry(page, &ctx->pages, lru)
+		KUNIT_ASSERT_TRUE(test, direct_map_sensitive(page));
+}
+
+static struct kunit_case asi_test_cases[] = {
+	KUNIT_CASE(test_alloc_sensitive_nonsensitive),
+	{}
+};
+
+static unsigned long taint_pre;
+
+static int store_taint_pre(struct kunit *test)
+{
+	taint_pre = get_taint();
+	return 0;
+}
+
+static void check_taint_post(struct kunit *test)
+{
+	unsigned long new_taint = get_taint() & ~taint_pre;
+
+	KUNIT_EXPECT_EQ_MSG(test, new_taint, 0,
+		"Kernel newly tainted after test. Maybe a WARN?");
+}
+
+static struct kunit_suite asi_test_suite = {
+	.name = "asi",
+	.init = store_taint_pre,
+	.exit = check_taint_post,
+	.test_cases = asi_test_cases,
+};
+
+kunit_test_suite(asi_test_suite);
+
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
diff --git a/kernel/panic.c b/kernel/panic.c
index d9c7cd09aeb9fe22f05e0b05d26555e20e502d2f..6aa79c5192520af55cd473912d2ac802de687304 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -39,6 +39,7 @@
 #include <linux/sys_info.h>
 #include <trace/events/error_report.h>
 #include <asm/sections.h>
+#include <kunit/visibility.h>
 
 #define PANIC_TIMER_STEP 100
 #define PANIC_BLINK_SPD 18
@@ -737,6 +738,7 @@ unsigned long get_taint(void)
 {
 	return tainted_mask;
 }
+EXPORT_SYMBOL_IF_KUNIT(get_taint);
 
 /**
  * add_taint: add a taint flag if not already set.
diff --git a/mm/init-mm.c b/mm/init-mm.c
index 4600e7605cab43b4bce24b85ec1667db8b92dc80..456b8f7d2ab3bd7963a51908dff76713a4e65ab5 100644
--- a/mm/init-mm.c
+++ b/mm/init-mm.c
@@ -13,6 +13,8 @@
 #include <linux/iommu.h>
 #include <asm/mmu.h>
 
+#include <kunit/visibility.h>
+
 #ifndef INIT_MM_CONTEXT
 #define INIT_MM_CONTEXT(name)
 #endif
@@ -47,6 +49,7 @@ struct mm_struct init_mm = {
 	.cpu_bitmap	= CPU_BITS_NONE,
 	INIT_MM_CONTEXT(init_mm)
 };
+EXPORT_SYMBOL_IF_KUNIT(init_mm);
 
 void setup_initial_init_mm(void *start_code, void *end_code,
 			   void *end_data, void *brk)

-- 
2.50.1



  parent reply	other threads:[~2025-09-24 15:01 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-24 14:59 [PATCH 00/21] mm: ASI direct map management Brendan Jackman
2025-09-24 14:59 ` [PATCH 01/21] x86/mm/asi: Add CONFIG_MITIGATION_ADDRESS_SPACE_ISOLATION Brendan Jackman
2025-10-24 22:37   ` Borislav Petkov
2025-10-24 23:32     ` Brendan Jackman
2025-10-25  9:57       ` Borislav Petkov
2025-09-24 14:59 ` [PATCH 02/21] x86/mm/asi: add X86_FEATURE_ASI and asi= Brendan Jackman
2025-10-25 10:06   ` Borislav Petkov
2025-10-26 22:24     ` Brendan Jackman
2025-11-10 11:26       ` Borislav Petkov
2025-11-10 12:15         ` Brendan Jackman
2025-09-24 14:59 ` [PATCH 03/21] x86/mm: factor out phys_pgd_init() Brendan Jackman
2025-09-27 19:29   ` kernel test robot
2025-10-01 12:26     ` Brendan Jackman
2025-10-25 11:48   ` Borislav Petkov
2025-10-26 22:29     ` Brendan Jackman
2025-11-10 11:38       ` Borislav Petkov
2025-11-10 12:36         ` Brendan Jackman
2025-09-24 14:59 ` [PATCH 04/21] x86/mm/asi: set up asi_nonsensitive_pgd Brendan Jackman
2025-10-01 20:28   ` Dave Hansen
2025-10-02 14:05     ` Brendan Jackman
2025-10-02 16:14       ` Dave Hansen
2025-10-02 17:19         ` Brendan Jackman
2025-11-12 19:39           ` Dave Hansen
2025-11-11 14:55   ` Borislav Petkov
2025-11-11 17:53     ` Brendan Jackman
2025-09-24 14:59 ` [PATCH 05/21] x86/mm/pat: mirror direct map changes to ASI Brendan Jackman
2025-09-25 13:36   ` kernel test robot
2025-10-01 20:50   ` Dave Hansen
2025-10-02 14:31     ` Brendan Jackman
2025-10-02 16:40       ` Dave Hansen
2025-10-02 17:08         ` Brendan Jackman
2025-09-24 14:59 ` [PATCH 06/21] mm/page_alloc: add __GFP_SENSITIVE and always set it Brendan Jackman
2025-10-01 21:18   ` Dave Hansen
2025-10-02 14:34     ` Brendan Jackman
2025-09-24 14:59 ` [PATCH 07/21] mm: introduce for_each_free_list() Brendan Jackman
2025-09-24 14:59 ` [PATCH 08/21] mm: rejig pageblock mask definitions Brendan Jackman
2025-09-24 14:59 ` [PATCH 09/21] mm/page_alloc: Invert is_check_pages_enabled() check Brendan Jackman
2025-09-24 14:59 ` [PATCH 10/21] mm/page_alloc: remove ifdefs from pindex helpers Brendan Jackman
2025-09-24 14:59 ` [PATCH 11/21] mm: introduce freetype_t Brendan Jackman
2025-09-25 13:15   ` kernel test robot
2025-10-01 21:20   ` Dave Hansen
2025-10-02 14:39     ` Brendan Jackman
2025-09-24 14:59 ` [PATCH 12/21] mm/asi: encode sensitivity in freetypes and pageblocks Brendan Jackman
2025-09-24 14:59 ` [PATCH 13/21] mm/page_alloc_test: unit test pindex helpers Brendan Jackman
2025-09-25 13:36   ` kernel test robot
2025-09-24 14:59 ` [PATCH 14/21] x86/mm/pat: introduce cpa_fault option Brendan Jackman
2025-09-24 14:59 ` [PATCH 15/21] mm/page_alloc: rename ALLOC_NON_BLOCK back to _HARDER Brendan Jackman
2025-09-24 14:59 ` [PATCH 16/21] mm/page_alloc: introduce ALLOC_NOBLOCK Brendan Jackman
2025-09-24 14:59 ` [PATCH 17/21] mm/slub: defer application of gfp_allowed_mask Brendan Jackman
2025-09-24 14:59 ` [PATCH 18/21] mm/asi: support changing pageblock sensitivity Brendan Jackman
2025-09-24 14:59 ` [PATCH 19/21] mm/asi: bad_page() when ASI mappings are wrong Brendan Jackman
2025-09-24 14:59 ` [PATCH 20/21] x86/mm/asi: don't use global pages when ASI enabled Brendan Jackman
2025-09-24 14:59 ` Brendan Jackman [this message]
2025-09-25 17:51 ` [PATCH 00/21] mm: ASI direct map management Brendan Jackman
2025-09-30 19:51 ` Konrad Rzeszutek Wilk
2025-10-01  7:12   ` Brendan Jackman
2025-10-01 19:54 ` Dave Hansen
2025-10-01 20:22   ` Yosry Ahmed
2025-10-01 20:30     ` Dave Hansen
2025-10-02 11:05       ` Brendan Jackman
2025-10-01 20:59 ` Dave Hansen
2025-10-02  7:34   ` David Hildenbrand
2025-10-02 11:23   ` Brendan Jackman
2025-10-02 17:01     ` Dave Hansen
2025-10-02 19:19       ` Brendan Jackman

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=20250924-b4-asi-page-alloc-v1-21-2d861768041f@google.com \
    --to=jackmanb@google.com \
    --cc=Liam.Howlett@oracle.com \
    --cc=akpm@linux-foundation.org \
    --cc=axelrasmussen@google.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=david@redhat.com \
    --cc=derkling@google.com \
    --cc=hannes@cmpxchg.org \
    --cc=junaids@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=lorenzo.stoakes@oracle.com \
    --cc=luto@kernel.org \
    --cc=mhocko@suse.com \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=reijiw@google.com \
    --cc=rientjes@google.com \
    --cc=roman.gushchin@linux.dev \
    --cc=rppt@kernel.org \
    --cc=surenb@google.com \
    --cc=tglx@linutronix.de \
    --cc=vbabka@suse.cz \
    --cc=x86@kernel.org \
    --cc=yosry.ahmed@linux.dev \
    --cc=yuanchu@google.com \
    --cc=ziy@nvidia.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox