Hi, Mike, On Mon, Oct 7, 2024 at 2:30 PM Mike Rapoport <rppt@xxxxxxxxxx> wrote: > > From: "Mike Rapoport (Microsoft)" <rppt@xxxxxxxxxx> > > Add an API that will allow updates of the direct/linear map for a set of > physically contiguous pages. > > It will be used in the following patches. > > Signed-off-by: Mike Rapoport (Microsoft) <rppt@xxxxxxxxxx> > --- > arch/arm64/include/asm/set_memory.h | 1 + > arch/arm64/mm/pageattr.c | 10 ++++++++++ > arch/loongarch/include/asm/set_memory.h | 1 + > arch/loongarch/mm/pageattr.c | 21 +++++++++++++++++++++ > arch/riscv/include/asm/set_memory.h | 1 + > arch/riscv/mm/pageattr.c | 15 +++++++++++++++ > arch/s390/include/asm/set_memory.h | 1 + > arch/s390/mm/pageattr.c | 11 +++++++++++ > arch/x86/include/asm/set_memory.h | 1 + > arch/x86/mm/pat/set_memory.c | 8 ++++++++ > include/linux/set_memory.h | 6 ++++++ > 11 files changed, 76 insertions(+) > > diff --git a/arch/arm64/include/asm/set_memory.h b/arch/arm64/include/asm/set_memory.h > index 917761feeffd..98088c043606 100644 > --- a/arch/arm64/include/asm/set_memory.h > +++ b/arch/arm64/include/asm/set_memory.h > @@ -13,6 +13,7 @@ int set_memory_valid(unsigned long addr, int numpages, int enable); > > int set_direct_map_invalid_noflush(struct page *page); > int set_direct_map_default_noflush(struct page *page); > +int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid); > bool kernel_page_present(struct page *page); > > #endif /* _ASM_ARM64_SET_MEMORY_H */ > diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c > index 0e270a1c51e6..01225900293a 100644 > --- a/arch/arm64/mm/pageattr.c > +++ b/arch/arm64/mm/pageattr.c > @@ -192,6 +192,16 @@ int set_direct_map_default_noflush(struct page *page) > PAGE_SIZE, change_page_range, &data); > } > > +int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid) > +{ > + unsigned long addr = (unsigned long)page_address(page); > + > + if (!can_set_direct_map()) > + return 0; > + > + return set_memory_valid(addr, nr, valid); > +} > + > #ifdef CONFIG_DEBUG_PAGEALLOC > void __kernel_map_pages(struct page *page, int numpages, int enable) > { > diff --git a/arch/loongarch/include/asm/set_memory.h b/arch/loongarch/include/asm/set_memory.h > index d70505b6676c..55dfaefd02c8 100644 > --- a/arch/loongarch/include/asm/set_memory.h > +++ b/arch/loongarch/include/asm/set_memory.h > @@ -17,5 +17,6 @@ int set_memory_rw(unsigned long addr, int numpages); > bool kernel_page_present(struct page *page); > int set_direct_map_default_noflush(struct page *page); > int set_direct_map_invalid_noflush(struct page *page); > +int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid); > > #endif /* _ASM_LOONGARCH_SET_MEMORY_H */ > diff --git a/arch/loongarch/mm/pageattr.c b/arch/loongarch/mm/pageattr.c > index ffd8d76021d4..f14b40c968b4 100644 > --- a/arch/loongarch/mm/pageattr.c > +++ b/arch/loongarch/mm/pageattr.c > @@ -216,3 +216,24 @@ int set_direct_map_invalid_noflush(struct page *page) > > return __set_memory(addr, 1, __pgprot(0), __pgprot(_PAGE_PRESENT | _PAGE_VALID)); > } > + > +int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid) > +{ > + unsigned long addr = (unsigned long)page_address(page); > + pgprot_t set, clear; > + > + return __set_memory((unsigned long)page_address(page), nr, set, clear); This line should be removed. Huacai > + > + if (addr < vm_map_base) > + return 0; > + > + if (valid) { > + set = PAGE_KERNEL; > + clear = __pgprot(0); > + } else { > + set = __pgprot(0); > + clear = __pgprot(_PAGE_PRESENT | _PAGE_VALID); > + } > + > + return __set_memory(addr, 1, set, clear); > +} > diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h > index ab92fc84e1fc..ea263d3683ef 100644 > --- a/arch/riscv/include/asm/set_memory.h > +++ b/arch/riscv/include/asm/set_memory.h > @@ -42,6 +42,7 @@ static inline int set_kernel_memory(char *startp, char *endp, > > int set_direct_map_invalid_noflush(struct page *page); > int set_direct_map_default_noflush(struct page *page); > +int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid); > bool kernel_page_present(struct page *page); > > #endif /* __ASSEMBLY__ */ > diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c > index 271d01a5ba4d..d815448758a1 100644 > --- a/arch/riscv/mm/pageattr.c > +++ b/arch/riscv/mm/pageattr.c > @@ -386,6 +386,21 @@ int set_direct_map_default_noflush(struct page *page) > PAGE_KERNEL, __pgprot(_PAGE_EXEC)); > } > > +int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid) > +{ > + pgprot_t set, clear; > + > + if (valid) { > + set = PAGE_KERNEL; > + clear = __pgprot(_PAGE_EXEC); > + } else { > + set = __pgprot(0); > + clear = __pgprot(_PAGE_PRESENT); > + } > + > + return __set_memory((unsigned long)page_address(page), nr, set, clear); > +} > + > #ifdef CONFIG_DEBUG_PAGEALLOC > static int debug_pagealloc_set_page(pte_t *pte, unsigned long addr, void *data) > { > diff --git a/arch/s390/include/asm/set_memory.h b/arch/s390/include/asm/set_memory.h > index 06fbabe2f66c..240bcfbdcdce 100644 > --- a/arch/s390/include/asm/set_memory.h > +++ b/arch/s390/include/asm/set_memory.h > @@ -62,5 +62,6 @@ __SET_MEMORY_FUNC(set_memory_4k, SET_MEMORY_4K) > > int set_direct_map_invalid_noflush(struct page *page); > int set_direct_map_default_noflush(struct page *page); > +int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid); > > #endif > diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c > index 5f805ad42d4c..4c7ee74aa130 100644 > --- a/arch/s390/mm/pageattr.c > +++ b/arch/s390/mm/pageattr.c > @@ -406,6 +406,17 @@ int set_direct_map_default_noflush(struct page *page) > return __set_memory((unsigned long)page_to_virt(page), 1, SET_MEMORY_DEF); > } > > +int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid) > +{ > + unsigned long flags; > + > + if (valid) > + flags = SET_MEMORY_DEF; > + else > + flags = SET_MEMORY_INV; > + > + return __set_memory((unsigned long)page_to_virt(page), nr, flags); > +} > #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE) > > static void ipte_range(pte_t *pte, unsigned long address, int nr) > diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h > index 4b2abce2e3e7..cc62ef70ccc0 100644 > --- a/arch/x86/include/asm/set_memory.h > +++ b/arch/x86/include/asm/set_memory.h > @@ -89,6 +89,7 @@ int set_pages_rw(struct page *page, int numpages); > > int set_direct_map_invalid_noflush(struct page *page); > int set_direct_map_default_noflush(struct page *page); > +int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid); > bool kernel_page_present(struct page *page); > > extern int kernel_set_to_readonly; > diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c > index 44f7b2ea6a07..069e421c2247 100644 > --- a/arch/x86/mm/pat/set_memory.c > +++ b/arch/x86/mm/pat/set_memory.c > @@ -2444,6 +2444,14 @@ int set_direct_map_default_noflush(struct page *page) > return __set_pages_p(page, 1); > } > > +int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid) > +{ > + if (valid) > + return __set_pages_p(page, nr); > + > + return __set_pages_np(page, nr); > +} > + > #ifdef CONFIG_DEBUG_PAGEALLOC > void __kernel_map_pages(struct page *page, int numpages, int enable) > { > diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h > index e7aec20fb44f..3030d9245f5a 100644 > --- a/include/linux/set_memory.h > +++ b/include/linux/set_memory.h > @@ -34,6 +34,12 @@ static inline int set_direct_map_default_noflush(struct page *page) > return 0; > } > > +static inline int set_direct_map_valid_noflush(struct page *page, > + unsigned nr, bool valid) > +{ > + return 0; > +} > + > static inline bool kernel_page_present(struct page *page) > { > return true; > -- > 2.43.0 >