From: Will Deacon <will@kernel.org>
To: Brian Ruley <brian.ruley@gehealthcare.com>
Cc: Russell King <linux@armlinux.org.uk>,
Steve Capper <steve.capper@arm.com>,
Russell King <rmk+kernel@arm.linux.org.uk>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] mm/arm: pgtable: remove young bit check for pte_valid_user
Date: Thu, 9 Apr 2026 14:56:53 +0100 [thread overview]
Message-ID: <adewJetUv6wMiz9o@willie-the-truck> (raw)
In-Reply-To: <20260409125446.981747-1-brian.ruley@gehealthcare.com>
On Thu, Apr 09, 2026 at 03:54:45PM +0300, Brian Ruley wrote:
> Fixes cache desync, which can cause undefined instruction,
> translation and permission faults under heavy memory use.
>
> This is an old bug introduced in commit 1971188aa196 ("ARM: 7985/1: mm:
> implement pte_accessible for faulting mappings"), which included a check
> for the young bit of a PTE. The underlying assumption was that old pages
> are not cached, therefore, `__sync_icache_dcache' could be skipped
> entirely.
>
> However, under extreme memory pressure, page migrations happen
> frequently and the assumption of uncached "old" pages does not hold.
> Especially for systems that do not have swap, the migrated pages are
> unequivocally marked old. This presents a problem, as it is possible
> for the original page to be immediately mapped to another VA that
> happens to share the same cache index in VIPT I-cache (we found this
> bug on Cortex-A9). Without cache invalidation, the CPU will see the
> old mapping whose physical page can now be used for a different
> purpose, as illustrated below:
>
> Core Physical Memory
> +-------------------------------+ +------------------+
> | TLB | | |
> | VA_A 0xb6e6f -> pfn_q | | pfn_q: code |
> +-------------------------------+ +------------------+
> | I-cache |
> | set[VA_A bits] | tag=pfn_q |
> +-------------------------------+
>
> migrate (kcompactd):
> 1. copy pfn_q --> pfn_r
> 2. free pfn_q
> 3. pte: VA_a -> pfn_r
> 4. pte_mkold(pte) --> !young
> 5. ICIALLUIS skipped (because !young)
>
> pfn_src reused (OOM pressure):
> pte: VA_B -> pfn_q (different code)
>
> bug:
> Core Physical Memory
> +-------------------------------+ +------------------+
> | TLB (empty) | | pfn_r: old code |
> +-------------------------------+ | pfn_q: new code |
> | I-cache | +------------------+
> | set[VA_A bits] | tag=pfn_q |<--- wrong instructions
> +-------------------------------+
(nit: Do you have pfn_r and pfn_q mixed up in the "Physical Memory" box?)
> This was verified on ba16-based board (i.MX6Quad/Dual, Cortex-A9) by
> instrumenting the migration code to track recently migrated pages in a
> ring buffer and then dumping them in the undefined instruction fault
> handler. The bug can be triggered with `stress-ng':
>
> stress-ng --vm 4 --vm-bytes 2G --vm-method zero-one --verify
>
> Note that the system we tested on has only 2G of memory, so the test
> triggered the OOM-killer in our case.
>
> Fixes: 1971188aa196 ("ARM: 7985/1: mm: implement pte_accessible for faulting mappings")
> Signed-off-by: Brian Ruley <brian.ruley@gehealthcare.com>
> ---
> arch/arm/include/asm/pgtable.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
> index 6fa9acd6a7f5..e3a5b4a9a65f 100644
> --- a/arch/arm/include/asm/pgtable.h
> +++ b/arch/arm/include/asm/pgtable.h
> @@ -185,7 +185,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
> #define pte_exec(pte) (pte_isclear((pte), L_PTE_XN))
>
> #define pte_valid_user(pte) \
> - (pte_valid(pte) && pte_isset((pte), L_PTE_USER) && pte_young(pte))
> + (pte_valid(pte) && pte_isset((pte), L_PTE_USER))
This patch is from twelve years ago, so please forgive me for having
forgotten all of the details. However, my recollection is that when using
the classic/!lpae format (as you will be on Cortex-A9), page aging is
implemented by using invalid (translation faulting) ptes for 'old'
mappings.
So in the case you describe, we may well elide the I-cache maintenance,
but won't we also put down an invalid pte? If we later take a fault
on that, we should then perform the cache maintenance when installing
the young entry (via ptep_set_access_flags()). The more interesting part
is probably when the mapping for 'VA_B' is installed to map 'pfn_q' but,
again, I would've expected the cache maintenance to happen just prior to
installing the valid (young) mapping.
Please can you help me to understand the problem better?
Will
next prev parent reply other threads:[~2026-04-09 13:57 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-09 12:54 [PATCH] mm/arm: pgtable: remove young bit check for pte_valid_user Brian Ruley
2026-04-09 13:56 ` Will Deacon [this message]
2026-04-09 14:21 ` Russell King (Oracle)
2026-04-09 14:43 ` Russell King (Oracle)
2026-04-09 15:17 ` Brian Ruley
2026-04-09 16:00 ` Russell King (Oracle)
2026-04-09 14:15 ` Russell King (Oracle)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=adewJetUv6wMiz9o@willie-the-truck \
--to=will@kernel.org \
--cc=brian.ruley@gehealthcare.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=rmk+kernel@arm.linux.org.uk \
--cc=steve.capper@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox