From: "Russell King (Oracle)" <linux@armlinux.org.uk>
To: Will Deacon <will@kernel.org>
Cc: Brian Ruley <brian.ruley@gehealthcare.com>,
Steve Capper <steve.capper@arm.com>,
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 15:43:51 +0100 [thread overview]
Message-ID: <ade7JxU0V2RV3F2r@shell.armlinux.org.uk> (raw)
In-Reply-To: <adewJetUv6wMiz9o@willie-the-truck>
On Thu, Apr 09, 2026 at 02:56:53PM +0100, Will Deacon wrote:
> 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?)
I don't think so. pfn_r contains the code that _was_ in pfn_q before
the migration happened (the migration copied pfn_q to pfn_r).
Then, a short time later, the page for pfn_r is reallocated, with new
code placed into it, and then a new PTE is established for pfn_q -
however, this should be a young PTE (which will be necessary for the
mapping to be visible to userspace), and thus should cause
__sync_icache_dcache() to be called, resulting in __flush_icache_all()
if it is an executable mapping.
If it isn't an executable mapping (because pfn_q isn't code) then we
will skip the __flush_icache_all() for the new mapping.
However, the I-cache for the old PTE that was pfn_r and now is pfn_q
will not be present in the physical page tables. An attempt to execute
code from that mapping should fault, causing the MM to mark that PTE
young, and, as it's executable, it should result in
__flush_icache_all() being called.
Like you, I can't see any issue here.
I think we need to know exactly what happened to the old PTE entry
and the newer PTE entry that was subsequently established on the
lead-up to the undefined instruction exception.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
next prev parent reply other threads:[~2026-04-09 14:43 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
2026-04-09 14:21 ` Russell King (Oracle)
2026-04-09 14:43 ` Russell King (Oracle) [this message]
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=ade7JxU0V2RV3F2r@shell.armlinux.org.uk \
--to=linux@armlinux.org.uk \
--cc=brian.ruley@gehealthcare.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=steve.capper@arm.com \
--cc=will@kernel.org \
/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