* [PATCH v4 1/8] alpha: load the MMU context when switch_mm() switches the current task
2026-10-09 21:03 [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback Magnus Lindholm
@ 2026-10-09 21:03 ` Magnus Lindholm
2026-10-10 1:42 ` Matt Turner
2026-10-09 21:03 ` [PATCH v4 2/8] alpha: run check_mmu_context() from finish_arch_post_lock_switch() Magnus Lindholm
` (7 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Magnus Lindholm @ 2026-10-09 21:03 UTC (permalink / raw)
To: richard.henderson, mattst88, linux-kernel, linux-alpha; +Cc: linmag7, stable
ev5_switch_mm() only prepares the incoming PCB. The context is installed
by PAL_swpctx, which alpha_switch_to() issues against that PCB on the way
out of the scheduler.
Two callers reach switch_mm_irqs_off() without going through
alpha_switch_to(): kthread_use_mm(), which borrows an mm for the current
kernel thread, and sched_force_init_mm() on the CPU-hotplug teardown path.
Neither explicitly loads the context, so the task can carry on running
under whatever was loaded before while current->mm says otherwise.
The stale page-table root need not be swapper_pg_dir; it may belong to a
user process that ran on the CPU earlier, and the kthread's user accesses
can then read and write that process's memory wherever the stale mappings
allow. Translations taken that way can also end up tagged with the
borrowed mm's ASN: ev5_switch_mm() writes that ASN into the PCB, which the
next PAL_swpctx installs against the stale ptbr. An address the stale
tables do not map faults instead, and since do_page_fault() resolves
faults against current->mm without reloading the context, the same access
can fault again on return.
sched_force_init_mm() needs CONFIG_HOTPLUG_CPU, which alpha does not
support, so kthread_use_mm() is the only one of the two reachable in
practice; the fix below tests the caller's identity rather than
special-casing either one.
The scheduler passes the incoming task, which is not current until
alpha_switch_to() runs; both direct callers pass current. Test for that
and load the context the way activate_mm() does. Both hold interrupts
disabled across switch_mm_irqs_off(), so this completes before any
shootdown can be taken and needs no asn_lock handshake.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: <stable@vger.kernel.org>
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Tested-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Message-ID: <20261008195608.965266-2-linmag7@gmail.com>
---
arch/alpha/include/asm/mmu_context.h | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/arch/alpha/include/asm/mmu_context.h b/arch/alpha/include/asm/mmu_context.h
index eee8fe836a59..c5cf7dbe6161 100644
--- a/arch/alpha/include/asm/mmu_context.h
+++ b/arch/alpha/include/asm/mmu_context.h
@@ -130,6 +130,8 @@ __get_new_mm_context(struct mm_struct *mm, long cpu)
return next;
}
+extern void __load_new_mm_context(struct mm_struct *);
+
__EXTERN_INLINE void
ev5_switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
struct task_struct *next)
@@ -139,6 +141,15 @@ ev5_switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
unsigned long mmc;
long cpu = smp_processor_id();
+ /*
+ * kthread_use_mm() and sched_force_init_mm() switch current's mm
+ * without alpha_switch_to(), which is what loads the context.
+ */
+ if (next == current) {
+ __load_new_mm_context(next_mm);
+ return;
+ }
+
#ifdef CONFIG_SMP
cpu_data[cpu].asn_lock = 1;
barrier();
@@ -160,7 +171,6 @@ ev5_switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
task_thread_info(next)->pcb.asn = mmc & HARDWARE_ASN_MASK;
}
-extern void __load_new_mm_context(struct mm_struct *);
asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr,
long cause, struct pt_regs *regs);
--
2.43.0
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v4 1/8] alpha: load the MMU context when switch_mm() switches the current task
2026-10-09 21:03 ` [PATCH v4 1/8] alpha: load the MMU context when switch_mm() switches the current task Magnus Lindholm
@ 2026-10-10 1:42 ` Matt Turner
0 siblings, 0 replies; 14+ messages in thread
From: Matt Turner @ 2026-10-10 1:42 UTC (permalink / raw)
To: Magnus Lindholm; +Cc: richard.henderson, linux-kernel, linux-alpha, stable
On Fri, Oct 09, 2026 at 11:03:46PM +0200, Magnus Lindholm wrote:
> + /*
> + * kthread_use_mm() and sched_force_init_mm() switch current's mm
> + * without alpha_switch_to(), which is what loads the context.
> + */
There is a third one: do_shoot_lazy_tlb() in kernel/fork.c calls
switch_mm(mm, &init_mm, current) from an IPI. It needs
MMU_LAZY_TLB_SHOOTDOWN, which alpha does not select, and the
next == current test handles it the same way. Only the comment and the
changelog are short by one. My tags stand.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 2/8] alpha: run check_mmu_context() from finish_arch_post_lock_switch()
2026-10-09 21:03 [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback Magnus Lindholm
2026-10-09 21:03 ` [PATCH v4 1/8] alpha: load the MMU context when switch_mm() switches the current task Magnus Lindholm
@ 2026-10-09 21:03 ` Magnus Lindholm
2026-10-10 1:42 ` Matt Turner
2026-10-09 21:03 ` [PATCH v4 3/8] alpha: only use a targeted tbi() when the target mm is really current Magnus Lindholm
` (6 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Magnus Lindholm @ 2026-10-09 21:03 UTC (permalink / raw)
To: richard.henderson, mattst88, linux-kernel, linux-alpha; +Cc: linmag7, stable
check_mmu_context() clears asn_lock and acts on need_new_asn, but it
runs only as the tail of switch_to(), after alpha_switch_to() returns.
A newly forked task never gets there: its first context switch resumes
at ret_from_fork and reaches schedule_tail() without returning to the
code following alpha_switch_to(). New kernel threads take the same
path through schedule_tail().
asn_lock is left set on that CPU, so the new task can run with
interrupts enabled while shootdown IPIs keep taking the deferred path.
The handshake meant to complete those invalidations never runs.
Move check_mmu_context() to finish_arch_post_lock_switch(), which is
called by finish_task_switch() for both existing and newly created tasks.
Drop the now redundant call from switch_to().
The hook runs after finish_lock_switch() releases the rq lock and enables
interrupts. An IPI arriving before asn_lock is cleared retires the slot
through flush_tlb_other(); an IPI arriving afterwards can flush directly,
since PAL_swpctx has already installed the incoming context.
Set need_new_asn whether ev5_switch_mm() reuses or allocates an ASN. An
IPI in that interval can zero either slot. Without this, the allocated
case can return to user space with a live ASN but a zero context slot,
which a later context-based shootdown shortcut could mistake for an
inactive CPU. check_mmu_context() reloads only when the slot is zero.
Call the hook unconditionally. Alpha selects ARCH_NO_PREEMPT, and neither
kthread_use_mm() nor sched_force_init_mm() sleeps between the direct
switch and this hook. RCU_STRICT_GRACE_PERIOD can enable PREEMPT_COUNT,
but cannot make those callers migrate there. Testing preemptible() would
only leave asn_lock set in that configuration.
This requires the preceding direct-switch fix, "alpha: load the MMU
context when switch_mm() switches the current task". It installs the
borrowed context before kthread_use_mm() reaches this hook, so clearing
asn_lock cannot expose a targeted invalidate against the wrong context.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
---
arch/alpha/include/asm/mmu_context.h | 11 +++++++++--
arch/alpha/include/asm/switch_to.h | 1 -
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/alpha/include/asm/mmu_context.h b/arch/alpha/include/asm/mmu_context.h
index c5cf7dbe6161..e5a5737506db 100644
--- a/arch/alpha/include/asm/mmu_context.h
+++ b/arch/alpha/include/asm/mmu_context.h
@@ -161,8 +161,8 @@ ev5_switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
next_mm->context[cpu] = mmc;
}
#ifdef CONFIG_SMP
- else
- cpu_data[cpu].need_new_asn = 1;
+ /* A deferred shootdown can also invalidate a newly allocated ASN. */
+ cpu_data[cpu].need_new_asn = 1;
#endif
/* Always update the PCB ASN. Another thread may have allocated
@@ -191,6 +191,13 @@ do { \
#define check_mmu_context() do { } while(0)
#endif
+/* Alpha has no kernel preemption; these callers cannot migrate here. */
+#define finish_arch_post_lock_switch finish_arch_post_lock_switch
+static inline void finish_arch_post_lock_switch(void)
+{
+ check_mmu_context();
+}
+
__EXTERN_INLINE void
ev5_activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
{
diff --git a/arch/alpha/include/asm/switch_to.h b/arch/alpha/include/asm/switch_to.h
index 762b7f975310..35c4b2c9d992 100644
--- a/arch/alpha/include/asm/switch_to.h
+++ b/arch/alpha/include/asm/switch_to.h
@@ -9,7 +9,6 @@ extern struct task_struct *alpha_switch_to(unsigned long, struct task_struct *);
#define switch_to(P,N,L) \
do { \
(L) = alpha_switch_to(virt_to_phys(&task_thread_info(N)->pcb), (P)); \
- check_mmu_context(); \
} while (0)
#endif /* __ALPHA_SWITCH_TO_H */
--
2.43.0
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v4 2/8] alpha: run check_mmu_context() from finish_arch_post_lock_switch()
2026-10-09 21:03 ` [PATCH v4 2/8] alpha: run check_mmu_context() from finish_arch_post_lock_switch() Magnus Lindholm
@ 2026-10-10 1:42 ` Matt Turner
0 siblings, 0 replies; 14+ messages in thread
From: Matt Turner @ 2026-10-10 1:42 UTC (permalink / raw)
To: Magnus Lindholm; +Cc: richard.henderson, linux-kernel, linux-alpha, stable
On Fri, Oct 09, 2026 at 11:03:47PM +0200, Magnus Lindholm wrote:
> +/* Alpha has no kernel preemption; these callers cannot migrate here. */
Nothing in the file says who "these callers" are. Something like:
/*
* Also called from kthread_use_mm() with preemption enabled. Alpha has
* no kernel preemption, so the task is still on the CPU that ran
* switch_mm().
*/
> + /* A deferred shootdown can also invalidate a newly allocated ASN. */
> + cpu_data[cpu].need_new_asn = 1;
That closes the zero-slot case. I went through the window again with
this in place. An IPI that sees asn_lock zeroes the slot and the hook
reloads. One that arrives after asn_lock is cleared flushes the
context PAL_swpctx already loaded, and the hook finds the slot nonzero.
The hook's __load_new_mm_context() now runs with interrupts on, so an
IPI can nest inside it. Both are loading the same mm, so the worst
outcome is that it gets the same ASN twice. flush_tlb_mm() from process
context has always had that.
Reviewed-by: Matt Turner <mattst88@gmail.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 3/8] alpha: only use a targeted tbi() when the target mm is really current
2026-10-09 21:03 [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback Magnus Lindholm
2026-10-09 21:03 ` [PATCH v4 1/8] alpha: load the MMU context when switch_mm() switches the current task Magnus Lindholm
2026-10-09 21:03 ` [PATCH v4 2/8] alpha: run check_mmu_context() from finish_arch_post_lock_switch() Magnus Lindholm
@ 2026-10-09 21:03 ` Magnus Lindholm
2026-10-09 21:03 ` [PATCH v4 4/8] alpha: invalidate the local context in flush_tlb_page() Magnus Lindholm
` (5 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Magnus Lindholm @ 2026-10-09 21:03 UTC (permalink / raw)
To: richard.henderson, mattst88, linux-kernel, linux-alpha; +Cc: linmag7, stable
ipi_flush_tlb_page() gates a targeted tbi() on current->active_mm.
tbi() acts on the address space context currently loaded on the CPU, so
it is only guaranteed to reach an mm's translations when a thread of
that mm is running there. current->active_mm is not sufficient: under
lazy TLB an idle or kernel task keeps an mm as its active_mm while a
different ASN is loaded, so the invalidate is issued against the wrong
context and the stale entry can survive. Nothing retires the old ASN
afterwards either, mm->context[cpu] still being valid, so the resuming
thread can reuse it.
Test current->mm instead and otherwise fall back to flush_tlb_other(),
which clears mm->context[cpu] and forces a fresh ASN at the next switch
whatever is loaded now.
For an mm borrowed through kthread_use_mm(), the prerequisite direct-switch
fix installs the context before the task can take a shootdown IPI. The
current->mm test therefore covers that case as well.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reviewed-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Message-ID: <20260923074903.862898-3-linmag7@gmail.com>
---
arch/alpha/kernel/smp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index ed06367ece57..1ad448105201 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -669,7 +669,8 @@ ipi_flush_tlb_page(void *x)
struct flush_tlb_page_struct *data = x;
struct mm_struct * mm = data->mm;
- if (mm == current->active_mm && !asn_locked())
+ /* A targeted tbi() needs a thread of MM to be current. */
+ if (mm == current->mm && !asn_locked())
flush_tlb_current_page(mm, data->vma, data->addr);
else
flush_tlb_other(mm);
--
2.43.0
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 4/8] alpha: invalidate the local context in flush_tlb_page()
2026-10-09 21:03 [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback Magnus Lindholm
` (2 preceding siblings ...)
2026-10-09 21:03 ` [PATCH v4 3/8] alpha: only use a targeted tbi() when the target mm is really current Magnus Lindholm
@ 2026-10-09 21:03 ` Magnus Lindholm
2026-10-10 1:44 ` Matt Turner
2026-10-09 21:03 ` [PATCH v4 5/8] alpha: fix the local TLB invalidate " Magnus Lindholm
` (4 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Magnus Lindholm @ 2026-10-09 21:03 UTC (permalink / raw)
To: richard.henderson, mattst88, linux-kernel, linux-alpha; +Cc: linmag7, stable
When the target mm is not the calling CPU's active_mm, flush_tlb_page()
does nothing locally, and smp_call_function() reaches only the other CPUs.
This CPU may still
hold translations for the mm and can later reuse the old ASN together with
them.
Add the missing else branch. flush_tlb_other() clears mm->context[cpu] so
a fresh ASN is taken at the next switch. Add this before changing the
current->active_mm test to current->mm: that change will also send lazy
callers here, so their local invalidate must already be in place.
The uniprocessor implementations of flush_tlb_mm() and
flush_icache_user_page() in asm/tlbflush.h and asm/cacheflush.h already
contain exactly this branch.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reviewed-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Message-ID: <20260923074903.862898-5-linmag7@gmail.com>
---
arch/alpha/kernel/smp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 1ad448105201..e4ba0aab8a66 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -697,6 +697,9 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
preempt_enable();
return;
}
+ } else {
+ /* smp_call_function() does not call back into this CPU. */
+ flush_tlb_other(mm);
}
data.vma = vma;
--
2.43.0
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v4 4/8] alpha: invalidate the local context in flush_tlb_page()
2026-10-09 21:03 ` [PATCH v4 4/8] alpha: invalidate the local context in flush_tlb_page() Magnus Lindholm
@ 2026-10-10 1:44 ` Matt Turner
0 siblings, 0 replies; 14+ messages in thread
From: Matt Turner @ 2026-10-10 1:44 UTC (permalink / raw)
To: Magnus Lindholm; +Cc: richard.henderson, linux-kernel, linux-alpha, stable
On Fri, Oct 09, 2026 at 11:03:49PM +0200, Magnus Lindholm wrote:
> Add this before changing the
> current->active_mm test to current->mm: that change will also send lazy
> callers here, so their local invalidate must already be in place.
Thanks, this is the order I wanted. With only this patch applied a lazy
caller still does the old targeted tbi(), so no step is worse than the
one before it.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 5/8] alpha: fix the local TLB invalidate in flush_tlb_page()
2026-10-09 21:03 [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback Magnus Lindholm
` (3 preceding siblings ...)
2026-10-09 21:03 ` [PATCH v4 4/8] alpha: invalidate the local context in flush_tlb_page() Magnus Lindholm
@ 2026-10-09 21:03 ` Magnus Lindholm
2026-10-09 21:03 ` [PATCH v4 6/8] alpha: fix the local TLB invalidate in the UP flush_tlb_page() Magnus Lindholm
` (3 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Magnus Lindholm @ 2026-10-09 21:03 UTC (permalink / raw)
To: richard.henderson, mattst88, linux-kernel, linux-alpha; +Cc: linmag7, stable
flush_tlb_page() invalidates the calling CPU itself before asking the
others, and gates that on current->active_mm. For a non-executable vma
that means a targeted tbi(2, addr), which acts on the context currently
loaded and is only guaranteed to invalidate the intended translations
when the target mm's context is the loaded one. A lazy active_mm does
not establish that, so as in ipi_flush_tlb_page() the target mm's stale
translations can survive, and nothing forces the old ASN to be retired
afterwards.
Test current->mm instead. A lazy caller then takes the flush_tlb_other()
branch added by the previous patch, retiring its local context. Adding
that branch first preserves the local invalidate at every step, including
on EV7 where a targeted tbi() against a foreign ASN appeared to work.
Which callers reach here with a foreign mm depends on the configuration.
folio_mkclean(), from the writeback flusher kworker that has no mm of its
own, accounted for about half the calls during writeback of a shared
mapping and none at all on anonymous memory. Those counts were measured
with CONFIG_COMPACTION=n: with COMPACTION=y, asm/pgtable.h overrides
ptep_clear_flush() to call migrate_flush_tlb_page(), which rendezvouses
with every CPU and handles the context itself, so folio_mkclean() does
not reach this function.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reviewed-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Message-ID: <20260923074903.862898-4-linmag7@gmail.com>
---
arch/alpha/kernel/smp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index e4ba0aab8a66..a5a42ae4a7d8 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -684,7 +684,8 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
preempt_disable();
- if (mm == current->active_mm) {
+ /* As in ipi_flush_tlb_page(): a targeted tbi() needs MM current. */
+ if (mm == current->mm) {
flush_tlb_current_page(mm, vma, addr);
if (atomic_read(&mm->mm_users) <= 1) {
int cpu, this_cpu = smp_processor_id();
--
2.43.0
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 6/8] alpha: fix the local TLB invalidate in the UP flush_tlb_page()
2026-10-09 21:03 [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback Magnus Lindholm
` (4 preceding siblings ...)
2026-10-09 21:03 ` [PATCH v4 5/8] alpha: fix the local TLB invalidate " Magnus Lindholm
@ 2026-10-09 21:03 ` Magnus Lindholm
2026-10-09 21:03 ` [PATCH v4 7/8] alpha: invalidate the local context in flush_tlb_mm() Magnus Lindholm
` (2 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Magnus Lindholm @ 2026-10-09 21:03 UTC (permalink / raw)
To: richard.henderson, mattst88, linux-kernel, linux-alpha; +Cc: linmag7, stable
The uniprocessor flush_tlb_page() in asm/tlbflush.h has the same wrong
test as the SMP one: a targeted tbi() is only guaranteed to invalidate
the intended translations when the target mm's context is loaded, but
the gate is current->active_mm, which a lazily borrowed mm also
satisfies.
Test current->mm instead. The else branch it falls to already exists
here, so unlike the SMP side this is the whole fix.
arch/alpha/kernel/smp.c is not built with CONFIG_SMP=n, so this is how
the same defect reaches a uniprocessor, where the flusher kworker
necessarily shares the only CPU with the writer.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reviewed-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Message-ID: <20260923074903.862898-6-linmag7@gmail.com>
---
arch/alpha/include/asm/tlbflush.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/alpha/include/asm/tlbflush.h b/arch/alpha/include/asm/tlbflush.h
index 0c8529997f54..9ae1902faf8e 100644
--- a/arch/alpha/include/asm/tlbflush.h
+++ b/arch/alpha/include/asm/tlbflush.h
@@ -87,7 +87,8 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
{
struct mm_struct *mm = vma->vm_mm;
- if (mm == current->active_mm)
+ /* A targeted tbi() needs a thread of MM to be current. */
+ if (mm == current->mm)
flush_tlb_current_page(mm, vma, addr);
else
flush_tlb_other(mm);
--
2.43.0
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 7/8] alpha: invalidate the local context in flush_tlb_mm()
2026-10-09 21:03 [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback Magnus Lindholm
` (5 preceding siblings ...)
2026-10-09 21:03 ` [PATCH v4 6/8] alpha: fix the local TLB invalidate in the UP flush_tlb_page() Magnus Lindholm
@ 2026-10-09 21:03 ` Magnus Lindholm
2026-10-09 21:03 ` [PATCH v4 8/8] alpha: invalidate the local context in flush_icache_user_page() Magnus Lindholm
2026-10-10 1:42 ` [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback Matt Turner
8 siblings, 0 replies; 14+ messages in thread
From: Magnus Lindholm @ 2026-10-09 21:03 UTC (permalink / raw)
To: richard.henderson, mattst88, linux-kernel, linux-alpha; +Cc: linmag7, stable
flush_tlb_mm() has the same caller-CPU omission that was fixed in
flush_tlb_page(): when the target mm is not the calling CPU's active_mm
nothing happens locally, and smp_call_function() handles only the other
CPUs, so this CPU may later reuse the old ASN together with the
translations it still holds.
The active_mm test itself is left alone here. That path calls
flush_tlb_current(), which loads a fresh context through
__load_new_mm_context() rather than issuing a targeted tbi() against
whatever ASN happens to be loaded, so it does not depend on which context
is current.
The uniprocessor implementation in asm/tlbflush.h already has the missing
branch. Counted over a fork-heavy run, flush_tlb_mm() was entered with the
mm not this CPU's active_mm 2934 times, and 632 times while otherwise idle.
The proposed Alpha hugetlb support routes hugetlb invalidations through
flush_tlb_range(), which calls this function. Unmapping or migrating a
hugetlb folio from another context will also need this local invalidate.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reviewed-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Message-ID: <20260923074903.862898-7-linmag7@gmail.com>
---
arch/alpha/kernel/smp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index a5a42ae4a7d8..988e397b0b8a 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -649,6 +649,9 @@ flush_tlb_mm(struct mm_struct *mm)
preempt_enable();
return;
}
+ } else {
+ /* smp_call_function() does not call back into this CPU. */
+ flush_tlb_other(mm);
}
smp_call_function(ipi_flush_tlb_mm, mm, 1);
--
2.43.0
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v4 8/8] alpha: invalidate the local context in flush_icache_user_page()
2026-10-09 21:03 [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback Magnus Lindholm
` (6 preceding siblings ...)
2026-10-09 21:03 ` [PATCH v4 7/8] alpha: invalidate the local context in flush_tlb_mm() Magnus Lindholm
@ 2026-10-09 21:03 ` Magnus Lindholm
2026-10-10 1:42 ` [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback Matt Turner
8 siblings, 0 replies; 14+ messages in thread
From: Magnus Lindholm @ 2026-10-09 21:03 UTC (permalink / raw)
To: richard.henderson, mattst88, linux-kernel, linux-alpha; +Cc: linmag7, stable
flush_icache_user_page() has the same caller-CPU omission that the
previous patch fixed in flush_tlb_mm(): when the target mm is not the
calling CPU's active_mm nothing happens locally, and smp_call_function()
handles only the other CPUs, so this CPU may later reuse the old ASN
together with the translations it still holds.
This matters here in particular because the function exists for
operating on another process's mappings: the comment above it describes
setting breakpoints through ptrace, and access_remote_vm() reaches it
through copy_to_user_page(). The calling CPU is therefore often running
something other than the target mm.
As in flush_tlb_mm(), the uniprocessor implementation in
asm/cacheflush.h already has the missing case.
No imb() is needed, here or in ipi_flush_icache_page(). Alpha's
user-space I-cache flush works by allocating a new ASN rather than by
invalidating the I-cache: the entries stay, but they are tagged with the
old ASN and can no longer match. An imb() is only required when the ASN
space wraps and numbers are reused, and __get_new_mm_context() already
does one in that case.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reviewed-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Message-ID: <20260923074903.862898-8-linmag7@gmail.com>
---
arch/alpha/kernel/smp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 988e397b0b8a..e21bc3920bec 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -758,6 +758,9 @@ flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
preempt_enable();
return;
}
+ } else {
+ /* smp_call_function() does not call back into this CPU. */
+ flush_tlb_other(mm);
}
smp_call_function(ipi_flush_icache_page, mm, 1);
--
2.43.0
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback
2026-10-09 21:03 [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback Magnus Lindholm
` (7 preceding siblings ...)
2026-10-09 21:03 ` [PATCH v4 8/8] alpha: invalidate the local context in flush_icache_user_page() Magnus Lindholm
@ 2026-10-10 1:42 ` Matt Turner
2026-10-10 1:45 ` Matt Turner
8 siblings, 1 reply; 14+ messages in thread
From: Matt Turner @ 2026-10-10 1:42 UTC (permalink / raw)
To: Magnus Lindholm; +Cc: richard.henderson, linux-kernel, linux-alpha
On Fri, Oct 09, 2026 at 11:03:45PM +0200, Magnus Lindholm wrote:
> Changes since v3:
All three things I asked for in v3 are here. Compile-tested SMP and UP
at each commit, nothing run on hardware yet.
Patches 1 and 3-8 have a Message-ID: trailer pointing at the previous
posting, I assume from git am -m. Please drop those when you apply.
Two changelog leftovers, neither worth a v5:
3/8 still says "the prerequisite direct-switch fix". That is patch 1
of this series now.
4/8 has a short line in the first paragraph ("This CPU may still").
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback
2026-10-10 1:42 ` [PATCH v4 0/8] alpha: fix stale TLB translations breaking copy-on-write and writeback Matt Turner
@ 2026-10-10 1:45 ` Matt Turner
0 siblings, 0 replies; 14+ messages in thread
From: Matt Turner @ 2026-10-10 1:45 UTC (permalink / raw)
To: Magnus Lindholm; +Cc: richard.henderson, linux-kernel, linux-alpha
On Fri, Oct 9, 2026 at 9:42 PM Matt Turner <mattst88@gmail.com> wrote:
>
> On Fri, Oct 09, 2026 at 11:03:45PM +0200, Magnus Lindholm wrote:
> > Changes since v3:
>
> All three things I asked for in v3 are here. Compile-tested SMP and UP
> at each commit, nothing run on hardware yet.
>
> Patches 1 and 3-8 have a Message-ID: trailer pointing at the previous
> posting, I assume from git am -m. Please drop those when you apply.
>
> Two changelog leftovers, neither worth a v5:
>
> 3/8 still says "the prerequisite direct-switch fix". That is patch 1
> of this series now.
>
> 4/8 has a short line in the first paragraph ("This CPU may still").
I should add, the whole series is
Reviewed-by: Matt Turner <mattst88@gmail.com>
^ permalink raw reply [flat|nested] 14+ messages in thread