[PATCH v7 2/3] arm64/mm: add set_direct_map_ro()

From: Xueyuan Chen

Date: Tue Sep 01 2026 - 11:41:50 EST


Implement set_direct_map_ro() for arm64 and flush the TLB internally.

Co-developed-by: Lance Yang <lance.yang@xxxxxxxxx>
Signed-off-by: Lance Yang <lance.yang@xxxxxxxxx>
Signed-off-by: Xueyuan Chen <xueyuan.chen21@xxxxxxxxx>
---
arch/arm64/include/asm/set_memory.h | 2 ++
arch/arm64/mm/pageattr.c | 12 ++++++++++++
2 files changed, 14 insertions(+)

diff --git a/arch/arm64/include/asm/set_memory.h b/arch/arm64/include/asm/set_memory.h
index 0091ba12200e..1be86dc11543 100644
--- a/arch/arm64/include/asm/set_memory.h
+++ b/arch/arm64/include/asm/set_memory.h
@@ -13,6 +13,8 @@ int set_memory_valid(unsigned long addr, int numpages, int enable);

int set_direct_map_invalid_noflush(struct page *page, unsigned int numpages);
int set_direct_map_default_noflush(struct page *page, unsigned int numpages);
+int set_direct_map_ro(struct page *page, unsigned int nr);
+#define set_direct_map_ro set_direct_map_ro
bool kernel_page_present(struct page *page);

int set_memory_encrypted(unsigned long addr, int numpages);
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index 132938b32eb1..0e95cd904ccb 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -355,6 +355,18 @@ int realm_register_memory_enc_ops(void)
return arm64_mem_crypt_ops_register(&realm_crypt_ops);
}

+int set_direct_map_ro(struct page *page, unsigned int nr)
+{
+ unsigned long addr = (unsigned long)page_address(page);
+
+ if (!can_set_direct_map())
+ return 0;
+
+ return __change_memory_common(addr, PAGE_SIZE * nr,
+ __pgprot(PTE_RDONLY),
+ __pgprot(PTE_WRITE));
+}
+
#ifdef CONFIG_DEBUG_PAGEALLOC
void __kernel_map_pages(struct page *page, int numpages, int enable)
{
--
2.47.3