diff mbox series

[07/10] arm64: mm: Introduce head_pool routines to enable pgtabl allocation

Message ID 20240313125711.20651-8-piliu@redhat.com (mailing list archive)
State New, archived
Headers show
Series arm64: mm: Use __create_pgd_mapping_locked() in | expand

Commit Message

Pingfan Liu March 13, 2024, 12:57 p.m. UTC
__create_pgd_mapping_locked() needs pgtable_alloc parameter to allocate
memory for page table.

During the early boot, the memory for page table should be allocated
from init_idmap_pg_dir or init_pg_dir. This patch introduces routines to
allocate PAGE from the above pool.

Signed-off-by: Pingfan Liu <piliu@redhat.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
To: linux-arm-kernel@lists.infradead.org
---
 arch/arm64/mm/mmu_head.c | 42 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
diff mbox series

Patch

diff --git a/arch/arm64/mm/mmu_head.c b/arch/arm64/mm/mmu_head.c
index 2df91e62ddb0..801ebffe4209 100644
--- a/arch/arm64/mm/mmu_head.c
+++ b/arch/arm64/mm/mmu_head.c
@@ -54,6 +54,8 @@ 
 
 #include "mmu_inc.c"
 
+phys_addr_t headpool_pgtable_alloc(int unused_shift);
+
 void INSTRUMENT_OPTION mmu_head_create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
 					unsigned long virt, phys_addr_t size,
 					pgprot_t prot,
@@ -86,3 +88,43 @@  void INSTRUMENT_OPTION mmu_head_create_pgd_mapping(pgd_t *pgdir, phys_addr_t phy
 	}
 	__create_pgd_mapping_locked(pgdir, phys, virt, size, prot, pgtable_alloc, flags);
 }
+
+struct headpool {
+	phys_addr_t start;
+	unsigned long size;
+	unsigned long next_idx;
+} __aligned(8);
+
+struct headpool head_pool __initdata;
+
+void INSTRUMENT_OPTION headpool_init(phys_addr_t start, unsigned long size)
+{
+	struct headpool *pool;
+
+	asm volatile(
+		"adrp %0, head_pool;"
+		"add %0, %0, #:lo12:head_pool;"
+		: "=r" (pool)
+		:
+		:
+	);
+	pool->start = start;
+	pool->size = size;
+	pool->next_idx = 0;
+}
+
+phys_addr_t INSTRUMENT_OPTION headpool_pgtable_alloc(int unused_shift)
+{
+	struct headpool *pool;
+	unsigned long idx;
+
+	asm volatile(
+		"adrp %0, head_pool;"
+		"add %0, %0, #:lo12:head_pool;"
+		: "=r" (pool)
+		:
+		:
+	);
+	idx = pool->next_idx++;
+	return pool->start + (idx << PAGE_SHIFT);
+}