linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alexandru Elisei <alexandru.elisei@arm.com>
To: catalin.marinas@arm.com, will@kernel.org, oliver.upton@linux.dev,
	maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com,
	yuzenghui@huawei.com, arnd@arndb.de, akpm@linux-foundation.org,
	mingo@redhat.com, peterz@infradead.org, juri.lelli@redhat.com,
	vincent.guittot@linaro.org, dietmar.eggemann@arm.com,
	rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de,
	bristot@redhat.com, vschneid@redhat.com, mhiramat@kernel.org,
	rppt@kernel.org, hughd@google.com
Cc: pcc@google.com, steven.price@arm.com, anshuman.khandual@arm.com,
	vincenzo.frascino@arm.com, david@redhat.com, eugenis@google.com,
	kcc@google.com, hyesoo.yu@samsung.com,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, kvmarm@lists.linux.dev,
	linux-fsdevel@vger.kernel.org, linux-arch@vger.kernel.org,
	linux-mm@kvack.org, linux-trace-kernel@vger.kernel.org
Subject: [PATCH RFC v3 20/35] arm64: mte: Add tag storage memory to CMA
Date: Thu, 25 Jan 2024 16:42:41 +0000	[thread overview]
Message-ID: <20240125164256.4147-21-alexandru.elisei@arm.com> (raw)
In-Reply-To: <20240125164256.4147-1-alexandru.elisei@arm.com>

Add the MTE tag storage pages to CMA, which allows the page allocator to
manage them like regular pages.

The CMA migratype lends the tag storage pages some very desirable
properties:

* They cannot be longterm pinned, meaning they should always be migratable.

* The pages can be allocated explicitely by using their PFN (with
  alloc_cma_range()) when they are needed to store tags.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---

Changes since v2:

* Reworked from rfc v2 patch #12 ("arm64: mte: Add tag storage pages to the
MIGRATE_CMA migratetype").
* Tag storage memory is now added to the cma_areas array and will be managed
like a regular CMA region (David Hildenbrand).
* If a tag storage region spans multiple zones, CMA won't be able to activate
the region. Split such regions into multiple tag storage regions (Hyesoo Yu).

 arch/arm64/Kconfig                  |   1 +
 arch/arm64/kernel/mte_tag_storage.c | 150 +++++++++++++++++++++++++++-
 2 files changed, 150 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 92d97930b56e..6f65e9005dc9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2085,6 +2085,7 @@ config ARM64_MTE
 if ARM64_MTE
 config ARM64_MTE_TAG_STORAGE
 	bool
+	select CONFIG_CMA
 	help
 	  Adds support for dynamic management of the memory used by the hardware
 	  for storing MTE tags. This memory, unlike normal memory, cannot be
diff --git a/arch/arm64/kernel/mte_tag_storage.c b/arch/arm64/kernel/mte_tag_storage.c
index 2f32265d8ad8..90b157132efa 100644
--- a/arch/arm64/kernel/mte_tag_storage.c
+++ b/arch/arm64/kernel/mte_tag_storage.c
@@ -5,6 +5,8 @@
  * Copyright (C) 2023 ARM Ltd.
  */
 
+#include <linux/cma.h>
+#include <linux/log2.h>
 #include <linux/memblock.h>
 #include <linux/mm.h>
 #include <linux/of.h>
@@ -22,6 +24,7 @@ struct tag_region {
 	struct range tag_range;	/* Tag storage memory, in PFNs. */
 	u32 block_size_pages;	/* Tag block size, in pages. */
 	phandle mem_phandle;	/* phandle for the associated memory node. */
+	struct cma *cma;	/* CMA cookie */
 };
 
 #define MAX_TAG_REGIONS	32
@@ -139,9 +142,88 @@ static int __init mte_find_tagged_memory_regions(void)
 	return -EINVAL;
 }
 
+static void __init mte_split_tag_region(struct tag_region *region, unsigned long last_tag_pfn)
+{
+	struct tag_region *new_region;
+	unsigned long last_mem_pfn;
+
+	new_region = &tag_regions[num_tag_regions];
+	last_mem_pfn = region->mem_range.start + (last_tag_pfn - region->tag_range.start) * 32;
+
+	new_region->mem_range.start = last_mem_pfn + 1;
+	new_region->mem_range.end = region->mem_range.end;
+	region->mem_range.end = last_mem_pfn;
+
+	new_region->tag_range.start = last_tag_pfn + 1;
+	new_region->tag_range.end = region->tag_range.end;
+	region->tag_range.end = last_tag_pfn;
+
+	new_region->block_size_pages = region->block_size_pages;
+
+	num_tag_regions++;
+}
+
+/*
+ * Split any tag region that spans multiple zones - CMA will fail if that
+ * happens.
+ */
+static int __init mte_split_tag_regions(void)
+{
+	struct tag_region *region;
+	struct range *tag_range;
+	struct zone *zone;
+	unsigned long pfn;
+	int i;
+
+	for (i = 0; i < num_tag_regions; i++) {
+		region = &tag_regions[i];
+		tag_range = &region->tag_range;
+		zone = page_zone(pfn_to_page(tag_range->start));
+
+		for (pfn = tag_range->start + 1; pfn <= tag_range->end; pfn++) {
+			if (page_zone(pfn_to_page(pfn)) == zone)
+				continue;
+
+			if (WARN_ON_ONCE(pfn % region->block_size_pages))
+				goto out_err;
+
+			if (num_tag_regions == MAX_TAG_REGIONS)
+				goto out_err;
+
+			mte_split_tag_region(&tag_regions[i], pfn - 1);
+			/* Move on to the next region. */
+			break;
+		}
+	}
+
+	return 0;
+
+out_err:
+	pr_err("Error splitting tag storage region 0x%llx-0x%llx spanning multiple zones",
+		PFN_PHYS(tag_range->start), PFN_PHYS(tag_range->end + 1) - 1);
+	return -EINVAL;
+}
+
 void __init mte_init_tag_storage(void)
 {
-	int ret;
+	unsigned long long mem_end;
+	struct tag_region *region;
+	unsigned long pfn, order;
+	u64 start, end;
+	int i, j, ret;
+
+	/*
+	 * Tag storage memory requires that tag storage pages in use for data
+	 * are always migratable when they need to be repurposed to store tags.
+	 * If ARCH_KEEP_MEMBLOCK is enabled, kexec will not scan reserved
+	 * memblocks when trying to find a suitable location for the kernel
+	 * image. This means that kexec will not use tag storage pages for
+	 * copying the kernel, and the pages will remain migratable.
+	 *
+	 * Add the check in case arm64 stops selecting ARCH_KEEP_MEMBLOCK by
+	 * default.
+	 */
+	BUILD_BUG_ON(!IS_ENABLED(CONFIG_ARCH_KEEP_MEMBLOCK));
 
 	if (num_tag_regions == 0)
 		return;
@@ -150,6 +232,72 @@ void __init mte_init_tag_storage(void)
 	if (ret)
 		goto out_disabled;
 
+	mem_end = PHYS_PFN(memblock_end_of_DRAM());
+
+	/*
+	 * MTE is disabled, tag storage pages can be used like any other pages.
+	 * The only restriction is that the pages cannot be used by kexec
+	 * because the memory remains marked as reserved in the memblock
+	 * allocator.
+	 */
+	if (!system_supports_mte()) {
+		for (i = 0; i< num_tag_regions; i++) {
+			start = tag_regions[i].tag_range.start;
+			end = tag_regions[i].tag_range.end;
+
+			/* end is inclusive, mem_end is not */
+			if (end >= mem_end)
+				end = mem_end - 1;
+			if (end < start)
+				continue;
+			for (pfn = start; pfn <= end; pfn++)
+				free_reserved_page(pfn_to_page(pfn));
+		}
+		goto out_disabled;
+	}
+
+	/*
+	 * Check that tag storage is addressable by the kernel.
+	 * cma_init_reserved_mem(), unlike cma_declare_contiguous_nid(), doesn't
+	 * perform this check.
+	 */
+	for (i = 0; i< num_tag_regions; i++) {
+		start = tag_regions[i].tag_range.start;
+		end = tag_regions[i].tag_range.end;
+
+		if (end >= mem_end) {
+			pr_err("Tag region 0x%llx-0x%llx outside addressable memory",
+				PFN_PHYS(start), PFN_PHYS(end + 1) - 1);
+			goto out_disabled;
+		}
+	}
+
+	ret = mte_split_tag_regions();
+	if (ret)
+		goto out_disabled;
+
+	for (i = 0; i < num_tag_regions; i++) {
+		region = &tag_regions[i];
+
+		/* Tag storage pages are managed in block_size_pages chunks. */
+		if (is_power_of_2(region->block_size_pages))
+			order = ilog2(region->block_size_pages);
+		else
+			order = 0;
+
+		ret = cma_init_reserved_mem(PFN_PHYS(region->tag_range.start),
+				PFN_PHYS(range_len(&region->tag_range)),
+				order, NULL, &region->cma);
+		if (ret) {
+			for (j = 0; j < i; j++)
+				cma_remove_mem(&region->cma);
+			goto out_disabled;
+		}
+
+		/* Keep pages reserved if activation fails. */
+		cma_reserve_pages_on_error(region->cma);
+	}
+
 	return;
 
 out_disabled:
-- 
2.43.0


  parent reply	other threads:[~2024-01-25 16:44 UTC|newest]

Thread overview: 95+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-25 16:42 [PATCH RFC v3 00/35] Add support for arm64 MTE dynamic tag storage reuse Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 01/35] mm: page_alloc: Add gfp_flags parameter to arch_alloc_page() Alexandru Elisei
2024-01-29  5:48   ` Anshuman Khandual
2024-01-29 11:41     ` Alexandru Elisei
2024-01-30  4:26       ` Anshuman Khandual
2024-01-30 11:56         ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 02/35] mm: page_alloc: Add an arch hook early in free_pages_prepare() Alexandru Elisei
2024-01-29  8:19   ` Anshuman Khandual
2024-01-29 11:42     ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 03/35] mm: page_alloc: Add an arch hook to filter MIGRATE_CMA allocations Alexandru Elisei
2024-01-29  8:44   ` Anshuman Khandual
2024-01-29 11:45     ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 04/35] mm: page_alloc: Partially revert "mm: page_alloc: remove stale CMA guard code" Alexandru Elisei
2024-01-29  9:01   ` Anshuman Khandual
2024-01-29 11:46     ` Alexandru Elisei
2024-01-30  4:34       ` Anshuman Khandual
2024-01-30 11:57         ` Alexandru Elisei
2024-01-31  3:27           ` Anshuman Khandual
2024-01-25 16:42 ` [PATCH RFC v3 05/35] mm: cma: Don't append newline when generating CMA area name Alexandru Elisei
2024-01-29  9:13   ` Anshuman Khandual
2024-01-29 11:46     ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 06/35] mm: cma: Make CMA_ALLOC_SUCCESS/FAIL count the number of pages Alexandru Elisei
2024-01-29  9:24   ` Anshuman Khandual
2024-01-29 11:51     ` Alexandru Elisei
2024-01-30  4:52       ` Anshuman Khandual
2024-01-30 11:58         ` Alexandru Elisei
2024-01-31  4:40           ` Anshuman Khandual
2024-01-31 13:27             ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 07/35] mm: cma: Add CMA_RELEASE_{SUCCESS,FAIL} events Alexandru Elisei
2024-01-29  9:31   ` Anshuman Khandual
2024-01-29 11:53     ` Alexandru Elisei
2024-01-31  5:59       ` Anshuman Khandual
2024-01-25 16:42 ` [PATCH RFC v3 08/35] mm: cma: Introduce cma_alloc_range() Alexandru Elisei
2024-01-30  5:20   ` Anshuman Khandual
2024-01-30 11:35     ` Alexandru Elisei
2024-01-31  6:24       ` Anshuman Khandual
2024-01-31 14:18         ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 09/35] mm: cma: Introduce cma_remove_mem() Alexandru Elisei
2024-01-30  5:50   ` Anshuman Khandual
2024-01-30 11:33     ` Alexandru Elisei
2024-01-31 13:19       ` Anshuman Khandual
2024-01-31 13:48         ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 10/35] mm: cma: Fast track allocating memory when the pages are free Alexandru Elisei
2024-01-30  9:18   ` Anshuman Khandual
2024-01-30 11:34     ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 11/35] mm: Allow an arch to hook into folio allocation when VMA is known Alexandru Elisei
2024-01-26 20:00   ` Peter Collingbourne
2024-01-29 11:59     ` Alexandru Elisei
2024-01-30  9:55   ` Anshuman Khandual
2024-01-30 11:34     ` Alexandru Elisei
2024-01-31  6:53       ` Anshuman Khandual
2024-01-31 12:22         ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 12/35] mm: Call arch_swap_prepare_to_restore() before arch_swap_restore() Alexandru Elisei
2024-02-01  3:30   ` Anshuman Khandual
2024-02-01 17:32     ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 13/35] mm: memory: Introduce fault-on-access mechanism for pages Alexandru Elisei
2024-02-01  5:52   ` Anshuman Khandual
2024-02-01 17:36     ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 14/35] of: fdt: Return the region size in of_flat_dt_translate_address() Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 15/35] of: fdt: Add of_flat_read_u32() Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 16/35] KVM: arm64: Don't deny VM_PFNMAP VMAs when kvm_has_mte() Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 17/35] arm64: mte: Rework naming for tag manipulation functions Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 18/35] arm64: mte: Rename __GFP_ZEROTAGS to __GFP_TAGGED Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 19/35] arm64: mte: Discover tag storage memory Alexandru Elisei
2024-01-26  8:50   ` Krzysztof Kozlowski
2024-01-26 17:01     ` Alexandru Elisei
2024-01-25 16:42 ` Alexandru Elisei [this message]
2024-01-25 16:42 ` [PATCH RFC v3 21/35] arm64: mte: Disable dynamic tag storage management if HW KASAN is enabled Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 22/35] arm64: mte: Enable tag storage if CMA areas have been activated Alexandru Elisei
2024-02-02 22:30   ` Evgenii Stepanov
2024-02-05 16:30     ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 23/35] arm64: mte: Try to reserve tag storage in arch_alloc_page() Alexandru Elisei
2024-01-30  0:04   ` Peter Collingbourne
2024-01-30 11:38     ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 24/35] arm64: mte: Perform CMOs for tag blocks Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 25/35] arm64: mte: Reserve tag block for the zero page Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 26/35] arm64: mte: Use fault-on-access to reserve missing tag storage Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 27/35] arm64: mte: Handle tag storage pages mapped in an MTE VMA Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 28/35] arm64: mte: swap: Handle tag restoring when missing tag storage Alexandru Elisei
2024-02-02  4:02   ` Peter Collingbourne
2024-02-02 14:56     ` Alexandru Elisei
2024-02-03  1:32       ` Evgenii Stepanov
2024-02-03  1:52       ` Peter Collingbourne
2024-01-25 16:42 ` [PATCH RFC v3 29/35] arm64: mte: copypage: " Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 30/35] arm64: mte: ptrace: Handle pages with " Alexandru Elisei
2024-02-01  9:21   ` Anshuman Khandual
2024-02-01 17:38     ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 31/35] khugepaged: arm64: Don't collapse MTE enabled VMAs Alexandru Elisei
2024-02-01  8:12   ` Anshuman Khandual
2024-02-01 17:38     ` Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 32/35] KVM: arm64: mte: Reserve tag storage for virtual machines with MTE Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 33/35] KVM: arm64: mte: Introduce VM_MTE_KVM VMA flag Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 34/35] arm64: mte: Enable dynamic tag storage management Alexandru Elisei
2024-01-25 16:42 ` [PATCH RFC v3 35/35] HACK! arm64: dts: Add fake tag storage to fvp-base-revc.dts Alexandru Elisei
2024-01-25 17:01 ` [PATCH RFC v3 00/35] Add support for arm64 MTE dynamic tag storage reuse Steven Rostedt

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=20240125164256.4147-21-alexandru.elisei@arm.com \
    --to=alexandru.elisei@arm.com \
    --cc=akpm@linux-foundation.org \
    --cc=anshuman.khandual@arm.com \
    --cc=arnd@arndb.de \
    --cc=bristot@redhat.com \
    --cc=bsegall@google.com \
    --cc=catalin.marinas@arm.com \
    --cc=david@redhat.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=eugenis@google.com \
    --cc=hughd@google.com \
    --cc=hyesoo.yu@samsung.com \
    --cc=james.morse@arm.com \
    --cc=juri.lelli@redhat.com \
    --cc=kcc@google.com \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=mgorman@suse.de \
    --cc=mhiramat@kernel.org \
    --cc=mingo@redhat.com \
    --cc=oliver.upton@linux.dev \
    --cc=pcc@google.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=rppt@kernel.org \
    --cc=steven.price@arm.com \
    --cc=suzuki.poulose@arm.com \
    --cc=vincent.guittot@linaro.org \
    --cc=vincenzo.frascino@arm.com \
    --cc=vschneid@redhat.com \
    --cc=will@kernel.org \
    --cc=yuzenghui@huawei.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;
as well as URLs for NNTP newsgroup(s).