[PATCH v6 3/3] x86/mm: add set_direct_map_ro_noflush()

David Hildenbrand (Arm) david at kernel.org
Tue Aug 25 08:52:53 PDT 2026


On 7/30/26 11:06, Xueyuan Chen wrote:
> Implement set_direct_map_ro_noflush() for x86 using CPA directly on the
> passed direct-map address. Clear _PAGE_RW and _PAGE_DIRTY, keep alias
> checks disabled like the existing direct-map _noflush helpers, and leave
> TLB invalidation to the caller.
> 
> Co-developed-by: Lance Yang <lance.yang at linux.dev>
> Signed-off-by: Lance Yang <lance.yang at linux.dev>
> Signed-off-by: Xueyuan Chen <xueyuan.chen21 at gmail.com>
> ---
>  arch/x86/include/asm/set_memory.h |  2 ++
>  arch/x86/mm/pat/set_memory.c      | 15 +++++++++++++++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
> index 4362c26aa992..bd3817e06052 100644
> --- a/arch/x86/include/asm/set_memory.h
> +++ b/arch/x86/include/asm/set_memory.h
> @@ -89,6 +89,8 @@ 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);
> +int set_direct_map_ro_noflush(const void *addr, unsigned long nr_pages);
> +#define set_direct_map_ro_noflush set_direct_map_ro_noflush
>  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 d023a40a1e03..5987f4c84f6f 100644
> --- a/arch/x86/mm/pat/set_memory.c
> +++ b/arch/x86/mm/pat/set_memory.c
> @@ -2662,6 +2662,21 @@ int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid)
>  	return __set_pages_np(page, nr);
>  }
>  
> +int set_direct_map_ro_noflush(const void *addr, unsigned long nr_pages)
> +{
> +	unsigned long tempaddr = (unsigned long)addr;
> +	struct cpa_data cpa = {
> +		.vaddr = &tempaddr,
> +		.pgd = NULL,
> +		.numpages = nr_pages,
> +		.mask_set = __pgprot(0),
> +		.mask_clr = __pgprot(_PAGE_RW | _PAGE_DIRTY),
> +		.flags = CPA_NO_CHECK_ALIAS,
> +	};
> +
> +	return __change_page_attr_set_clr(&cpa, 1);
> +}
> +
>  #ifdef CONFIG_DEBUG_PAGEALLOC
>  void __kernel_map_pages(struct page *page, int numpages, int enable)
>  {

We need an ack from x86 folks, to me this looks good.

-- 
Cheers,

David



More information about the linux-arm-kernel mailing list