[PATCH v3 04/11] arm64/mm: Add set_memory_device() and set_memory_normal()

From: Thierry Reding

Date: Wed Jul 01 2026 - 12:13:17 EST


From: Chun Ng <chunn@xxxxxxxxxx>

Add helpers to swap PROT_NORMAL and PROT_DEVICE_nGnRnE protection bits
on a kernel-linear-map range.

Signed-off-by: Chun Ng <chunn@xxxxxxxxxx>
Signed-off-by: Thierry Reding <treding@xxxxxxxxxx>
---
arch/arm64/include/asm/set_memory.h | 2 ++
arch/arm64/mm/pageattr.c | 16 ++++++++++++++++
include/linux/set_memory.h | 11 +++++++++++
3 files changed, 29 insertions(+)

diff --git a/arch/arm64/include/asm/set_memory.h b/arch/arm64/include/asm/set_memory.h
index 90f61b17275e..6a7030609789 100644
--- a/arch/arm64/include/asm/set_memory.h
+++ b/arch/arm64/include/asm/set_memory.h
@@ -10,6 +10,8 @@ bool can_set_direct_map(void);
#define can_set_direct_map can_set_direct_map

int set_memory_valid(unsigned long addr, int numpages, int enable);
+int set_memory_device(unsigned long addr, int numpages);
+int set_memory_normal(unsigned long addr, int numpages);

int set_direct_map_invalid_noflush(struct page *page);
int set_direct_map_default_noflush(struct page *page);
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index bbe98ac9ad8c..871b59a6c9ea 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -251,6 +251,22 @@ int set_memory_valid(unsigned long addr, int numpages, int enable)
__pgprot(PTE_PRESENT_VALID_KERNEL));
}

+int set_memory_device(unsigned long addr, int numpages)
+{
+ return __change_memory_common(addr, PAGE_SIZE * numpages,
+ __pgprot(PROT_DEVICE_nGnRnE),
+ __pgprot(PROT_NORMAL));
+}
+EXPORT_SYMBOL_GPL(set_memory_device);
+
+int set_memory_normal(unsigned long addr, int numpages)
+{
+ return __change_memory_common(addr, PAGE_SIZE * numpages,
+ __pgprot(PROT_NORMAL),
+ __pgprot(PROT_DEVICE_nGnRnE));
+}
+EXPORT_SYMBOL_GPL(set_memory_normal);
+
int set_direct_map_invalid_noflush(struct page *page)
{
pgprot_t clear_mask = __pgprot(PTE_PRESENT_VALID_KERNEL);
diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
index 3030d9245f5a..abcb11378fdb 100644
--- a/include/linux/set_memory.h
+++ b/include/linux/set_memory.h
@@ -72,6 +72,17 @@ static inline int clear_mce_nospec(unsigned long pfn)
}
#endif

+#ifndef CONFIG_ARM64
+static inline int set_memory_device(unsigned long addr, int numpages)
+{
+ return 0;
+}
+static inline int set_memory_normal(unsigned long addr, int numpages)
+{
+ return 0;
+}
+#endif
+
#ifndef CONFIG_ARCH_HAS_MEM_ENCRYPT
static inline int set_memory_encrypted(unsigned long addr, int numpages)
{

--
2.54.0