From nobody Thu Oct 2 02:12:35 2025 Received: from mail-ed1-f73.google.com (mail-ed1-f73.google.com [209.85.208.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B774230BBBD for ; Wed, 24 Sep 2025 15:00:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758726034; cv=none; b=ETpNQvMWfpzWBT3sKeDJ1T25C3XQZq1c6mnqrVaKy6q3neLxKd6/miozrgbQW1oFKZDlVapNnNPHi4dHduErDsqUUiwFLsqlBTXVNgt5HIvgytZR7pmifa5z5EvVZHkHGaf6VFMfIPwGOzo8NK/6UYR3J2Ovjnj3PG632eWU+JA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758726034; c=relaxed/simple; bh=qcUdbQm9f0IEEs//mdY+wa1apR9KiQeDm5678H0bicc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=JTQPW7pQnjsk3hugdZnRPHsEoFHleaouiPK51XxbaVVC9Ihej165if+E8jVGY3USfWuMbe7V42VKpFPK9kbGPlkhJMgYdA1HeXyil0CKBdIWmt1/7Lb+KfuCbitJjkVvM4lVdJQOdGJhK6oR444Un2KiGC2+FoUrn74aFz2tn3A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jackmanb.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=ZFhr6UCO; arc=none smtp.client-ip=209.85.208.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jackmanb.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ZFhr6UCO" Received: by mail-ed1-f73.google.com with SMTP id 4fb4d7f45d1cf-63049fca047so4240733a12.2 for ; Wed, 24 Sep 2025 08:00:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1758726030; x=1759330830; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=5L6wwf2TI57XEfLhcaZXMRQ+L/0zQiVmk9x1OVnFFiI=; b=ZFhr6UCOq6AmMkQMh3hxuDH16+PwR/ebFFtT/+bWT6YCQT9+VLY6EXHdCl/TTop7Ps bRqtMaO38ftXCN+Z5Nfm8y+vDCAkaa8OG5OfvpxaN/HUjZ2h3YaiO0vYKxaT2U9vHdJN A5UgKocdrijqfA0cfP4ZWFm7ZjOGYk1Lry6XJKyKFOQBmxT/bYTFa2ySQb9F9gMqzoDB xqOa2rtp3NlmnHK5CWDpt1aUzltsgA/7iIZkQzt7YRHNpUFF5qqSHqepjjwba28NQ9GE wf13nDzLnUAr1UPnX0vudsomsoTMn+uQ4yTidf3wfxi7lSl0/nMU7GC4+DSmDI71D+OY Dk0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758726030; x=1759330830; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=5L6wwf2TI57XEfLhcaZXMRQ+L/0zQiVmk9x1OVnFFiI=; b=P8BXfSvHF1EYJBTuUrgYjCJFKrzyyqjixphO/D/CVvM/D2Jegoo+pp8lzks+cgHFCe Wz3axxF8BF4uL2X5rMy0EAke0FvwvN54Z2eu1nrOspCt0auImCQ2xxmL1DEE3XFg6kmt WvlpJObTo9NRMYvkQV/ubmMF+Atpmj/5T2eXDfitEyI8dFC9gswHfTFieX8wdWYx08S3 IZxH2saV19AeibL5x0jd72eXAnwA0V0LXQfOm+KTz04Js4nLVew4QpTH9lDV8D9HZRe5 zyVrhSax2lDgKb0G/yeJJb4et3Auxcy798gsGguDz6+hUXEla6m4mvSsj8KkIf+m1v0t bZ2Q== X-Forwarded-Encrypted: i=1; AJvYcCWR1uDd3FhKLzW3yZa0jmVU9lGmhp+ZO4uODxGpgB98hp+YQXv9mSKtk3VS14MdXcr6p07ioeNcSc2uj9s=@vger.kernel.org X-Gm-Message-State: AOJu0YyhvXFHtHFi7AXkCD9guW5V17zWaxEsPVEni5mIhakVG74cngQq DLPCmtEFs1GM1cQLD47ps6FHxhzNitdZijZQMW4vVMnvPvIOcYPCKdQmwBK4YnlXlRNNTJTA1pH DggG74Gph0Y5mYQ== X-Google-Smtp-Source: AGHT+IHyYgPrnvJDNnriMm16XcgI4Z+GtksLauuH+Ta7oWXXcU6rl19T9F/meDi87vNPoKDDvgmVTSxx+6DjQQ== X-Received: from eddp6.prod.google.com ([2002:a05:6402:46c6:b0:634:824b:21e0]) (user=jackmanb job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6402:1ecd:b0:634:66c8:9e7d with SMTP id 4fb4d7f45d1cf-63467a209bbmr6324885a12.36.1758726029633; Wed, 24 Sep 2025 08:00:29 -0700 (PDT) Date: Wed, 24 Sep 2025 14:59:56 +0000 In-Reply-To: <20250924-b4-asi-page-alloc-v1-0-2d861768041f@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250924-b4-asi-page-alloc-v1-0-2d861768041f@google.com> X-Mailer: b4 0.14.2 Message-ID: <20250924-b4-asi-page-alloc-v1-21-2d861768041f@google.com> Subject: [PATCH 21/21] mm: asi_test: smoke test for [non]sensitive page allocs From: Brendan Jackman To: jackmanb@google.com, Andy Lutomirski , Lorenzo Stoakes , "Liam R. Howlett" , Suren Baghdasaryan , Michal Hocko , Johannes Weiner , Zi Yan , Axel Rasmussen , Yuanchu Xie , Roman Gushchin 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 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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=3Dx86_64 \ --kunitconfig=3Darch/x86/.kunitconfig --kernel_args asi=3Don 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=3Dx86_64 make O=3D.kunit menuconfig # Or debug.config or whatever tools/testing/kunit/kunit.py run --arch=3Dx86_64 --kernel_args asi=3Don Signed-off-by: Brendan Jackman --- 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..83219e6ecca8d2064aba71fab1f= 15d57161fa2e4 --- /dev/null +++ b/arch/x86/.kunitconfig @@ -0,0 +1,7 @@ +CONFIG_PCI=3Dy +CONFIG_MMU=3Dy +CONFIG_64BIT=3Dy +CONFIG_X86_64=3Dy +CONFIG_KUNIT=3Dy +CONFIG_MITIGATION_ADDRESS_SPACE_ISOLATION=3Dy +CONFIG_ASI_KUNIT_TESTS=3Dy \ No newline at end of file diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index cb874c3857cf443c6235e05bc3f070b0ea2686f0..a7b5658ecb1203458e06a0a065b= cc7aa7dca8538 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2458,6 +2458,13 @@ config MITIGATION_PAGE_TABLE_ISOLATION =20 See Documentation/arch/x86/pti.rst for more details. =20 +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..7c36ec7f24ebb285fcfc0100042= 06a57536fc990 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile @@ -58,3 +58,5 @@ obj-$(CONFIG_X86_MEM_ENCRYPT) +=3D mem_encrypt.o obj-$(CONFIG_AMD_MEM_ENCRYPT) +=3D mem_encrypt_amd.o =20 obj-$(CONFIG_AMD_MEM_ENCRYPT) +=3D mem_encrypt_boot.o + +obj-$(CONFIG_ASI_KUNIT_TESTS) +=3D 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..6076a61980ed9daea63113a30e9= 90eb02a7b08d5 --- /dev/null +++ b/arch/x86/mm/asi_test.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +struct free_pages_ctx { + unsigned int order; + struct list_head pages; +}; + +static void action_many__free_pages(void *context) +{ + struct free_pages_ctx *ctx =3D 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, transparen= tly + * take care of error handling and cleanup. Does this all via a single KUn= it + * 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 =3D kunit_kzalloc( + test, sizeof(struct free_pages_ctx), GFP_KERNEL); + + KUNIT_ASSERT_NOT_NULL(test, ctx); + INIT_LIST_HEAD(&ctx->pages); + ctx->order =3D order; + + for (int i =3D 0; i < count; i++) { + struct page *page =3D 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 =3D GFP_KERNEL | __GFP_THISNODE; + struct page *page; + + if (!cpu_feature_enabled(X86_FEATURE_ASI)) + kunit_skip(test, "ASI off. Set asi=3Don 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 =3D (node_present_pages(numa_node_id()) / 2) + 1; + ctx =3D 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 |=3D __GFP_SENSITIVE; + ctx =3D 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[] =3D { + KUNIT_CASE(test_alloc_sensitive_nonsensitive), + {} +}; + +static unsigned long taint_pre; + +static int store_taint_pre(struct kunit *test) +{ + taint_pre =3D get_taint(); + return 0; +} + +static void check_taint_post(struct kunit *test) +{ + unsigned long new_taint =3D 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 =3D { + .name =3D "asi", + .init =3D store_taint_pre, + .exit =3D check_taint_post, + .test_cases =3D 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..6aa79c5192520af55cd473912d2= ac802de687304 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -39,6 +39,7 @@ #include #include #include +#include =20 #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); =20 /** * add_taint: add a taint flag if not already set. diff --git a/mm/init-mm.c b/mm/init-mm.c index 4600e7605cab43b4bce24b85ec1667db8b92dc80..456b8f7d2ab3bd7963a51908dff= 76713a4e65ab5 100644 --- a/mm/init-mm.c +++ b/mm/init-mm.c @@ -13,6 +13,8 @@ #include #include =20 +#include + #ifndef INIT_MM_CONTEXT #define INIT_MM_CONTEXT(name) #endif @@ -47,6 +49,7 @@ struct mm_struct init_mm =3D { .cpu_bitmap =3D CPU_BITS_NONE, INIT_MM_CONTEXT(init_mm) }; +EXPORT_SYMBOL_IF_KUNIT(init_mm); =20 void setup_initial_init_mm(void *start_code, void *end_code, void *end_data, void *brk) --=20 2.50.1