[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1f4fcb81-7b29-4e7d-b2af-5fb06f4faaa2@arm.com>
Date: Tue, 27 Jan 2026 09:58:42 +0000
From: Ryan Roberts <ryan.roberts@....com>
To: Ard Biesheuvel <ardb+git@...gle.com>, linux-kernel@...r.kernel.org
Cc: linux-arm-kernel@...ts.infradead.org, will@...nel.org,
catalin.marinas@....com, mark.rutland@....com,
Ard Biesheuvel <ardb@...nel.org>,
Anshuman Khandual <anshuman.khandual@....com>,
Liz Prucka <lizprucka@...gle.com>, Seth Jenkins <sethjenkins@...gle.com>,
Kees Cook <kees@...nel.org>, linux-hardening@...r.kernel.org
Subject: Re: [PATCH v2 05/10] arm64: mm: Preserve non-contiguous descriptors
when mapping DRAM
On 26/01/2026 09:26, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@...nel.org>
>
> Instead of blindly overwriting existing live entries with the contiguous
> bit cleared when mapping DRAM regions, check whether the contiguous
> region in question starts with a descriptor that has the valid bit set
> and the contiguous bit cleared, and in that case, leave the contiguous
> bit unset on the entire region. This permits the logic of mapping the
> kernel's linear alias to be simplified in a subsequent patch.
>
> Note that not setting the contiguous bit on any of the descriptors in
> the contiguous region can only result in an invalid configuration if it
> was already invalid to begin with.
>
> Signed-off-by: Ard Biesheuvel <ardb@...nel.org>
Reviewed-by: Ryan Roberts <ryan.roberts@....com>
> ---
> arch/arm64/include/asm/pgtable.h | 4 ++++
> arch/arm64/mm/mmu.c | 6 ++++--
> 2 files changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 64d5f1d9cce9..cb2c4525e49a 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -224,6 +224,10 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
> * Returns true if the pte is valid and has the contiguous bit set.
> */
> #define pte_valid_cont(pte) (pte_valid(pte) && pte_cont(pte))
> +/*
> + * Returns true if the pte is valid and has the contiguous bit cleared.
> + */
> +#define pte_valid_noncont(pte) (pte_valid(pte) && !pte_cont(pte))
> /*
> * Could the pte be present in the TLB? We must check mm_tlb_flush_pending
> * so that we don't erroneously return false for pages that have been
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 28cc3cda042c..d7faa98f427c 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -230,7 +230,8 @@ static int alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
>
> /* use a contiguous mapping if the range is suitably aligned */
> if ((((addr | next | phys) & ~CONT_PTE_MASK) == 0) &&
> - (flags & NO_CONT_MAPPINGS) == 0)
> + (flags & NO_CONT_MAPPINGS) == 0 &&
> + !pte_valid_noncont(__ptep_get(ptep)))
> __prot = __pgprot(pgprot_val(prot) | PTE_CONT);
>
> init_pte(ptep, addr, next, phys, __prot);
> @@ -330,7 +331,8 @@ static int alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
>
> /* use a contiguous mapping if the range is suitably aligned */
> if ((((addr | next | phys) & ~CONT_PMD_MASK) == 0) &&
> - (flags & NO_CONT_MAPPINGS) == 0)
> + (flags & NO_CONT_MAPPINGS) == 0 &&
> + !pte_valid_noncont(pmd_pte(READ_ONCE(*pmdp))))
> __prot = __pgprot(pgprot_val(prot) | PTE_CONT);
>
> ret = init_pmd(pmdp, addr, next, phys, __prot, pgtable_alloc, flags);
Powered by blists - more mailing lists