@@ -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);
+}
__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(+)