Patch "s390/mm: fix local TLB flushing vs. detach of an mm address space" has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
s390/mm: fix local TLB flushing vs. detach of an mm address space
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
s390-mm-fix-local-tlb-flushing-vs.-detach-of-an-mm-address-space.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
b3e5dc45fd1ec2aa1de6b80008f9295eb17e0659Mon Sep 17 00:00:00 2001
From: Martin Schwidefsky <[email protected]>
Date: Wed, 16 Aug 2017 14:10:01 +0200
Subject: s390/mm: fix local TLB flushing vs. detach of an mm address space
From: Martin Schwidefsky <[email protected]>
commit b3e5dc45fd1ec2aa1de6b80008f9295eb17e0659 upstream.
The local TLB flushing code keeps an additional mask in the mm.context, the cpu_attach_mask. At the time a global flush of an address space is done the cpu_attach_mask is copied to the mm_cpumask in order to avoid future global flushes in case the mm is used by a single CPU only after the flush.
Trouble is that the reset of the mm_cpumask is racy against the detach of an mm address space by switch_mm. The current order is first the global TLB flush and then the copy of the cpu_attach_mask to the mm_cpumask. The order needs to be the other way around.
--- arch/s390/include/asm/mmu_context.h | 4 ++-- arch/s390/include/asm/tlbflush.h | 26 +++++--------------------- 2 files changed, 7 insertions(+), 23 deletions(-)
arch/s390/include/asm/mmu_context.h +2 -2
@@ -93,7 +93,6 @@ static inline void switch_mm(struct mm_sif (prev == next)return ;cpumask_set_cpu (cpu, &next->context.cpu_attach_mask); -cpumask_set_cpu (cpu,mm_cpumask (next));/* Clear old ASCE by loading the kernel ASCE. */ __ctl_load (S390_lowcore.kernel_asce,1 ,1 );__ctl_load (S390_lowcore.kernel_asce,7 ,7 );
@@ -111,7 +110,7 @@ static inline void finish_arch_post_lockpreempt_disable ();while (atomic_read (&mm->context.flush_count))cpu_relax (); - +cpumask_set_cpu (smp_processor_id (),mm_cpumask (mm));if (mm->context.flush_mm)__tlb_flush_mm (mm);preempt_enable ();
@@ -126,6 +125,7 @@ static inline void activate_mm(struct mm struct mm_struct *next) {switch_mm (prev, next, current); +cpumask_set_cpu (smp_processor_id (),mm_cpumask (next));set_user_asce (next); }
arch/s390/include/asm/tlbflush.h +5 -21
@@ -43,23 +43,6 @@ static inline void __tlb_flush_global(vo* Flush TLB entries for a specific mm on all CPUs (in case gmap is used * this implicates multiple ASCEs!). */ -static inline void __tlb_flush_full (struct mm_struct *mm) -{ -preempt_disable (); -atomic_inc (&mm->context.flush_count); -if (cpumask_equal (mm_cpumask (mm),cpumask_of (smp_processor_id ()))) { -/* Local TLB flush */ -__tlb_flush_local (); - }else { -/* Global TLB flush */ -__tlb_flush_global (); -/* Reset TLB flush mask */ -cpumask_copy (mm_cpumask (mm), &mm->context.cpu_attach_mask); - } -atomic_dec (&mm->context.flush_count); -preempt_enable (); -} -static inline void __tlb_flush_mm (struct mm_struct *mm) {unsigned long gmap_asce;
@@ -71,16 +54,18 @@ static inline void __tlb_flush_mm(struct*/ preempt_disable ();atomic_inc (&mm->context.flush_count); +/* Reset TLB flush mask */ +cpumask_copy (mm_cpumask (mm), &mm->context.cpu_attach_mask); +barrier (); gmap_asce =READ_ONCE (mm->context.gmap_asce);if (MACHINE_HAS_IDTE && gmap_asce !=-1UL ) {if (gmap_asce)__tlb_flush_idte (gmap_asce);__tlb_flush_idte (mm->context.asce); }else { -__tlb_flush_full (mm); +/* Global TLB flush */ +__tlb_flush_global (); } -/* Reset TLB flush mask */ -cpumask_copy (mm_cpumask (mm), &mm->context.cpu_attach_mask);atomic_dec (&mm->context.flush_count);preempt_enable (); }
@@ -94,7 +79,6 @@ static inline void __tlb_flush_kernel(vo }#else #define __tlb_flush_global () __tlb_flush_local() -#define __tlb_flush_full (mm) __tlb_flush_local()/* * Flush TLB entries for a specific ASCE on all CPUs.
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/s390-mm-fix-local-tlb-flushing-vs.-detach-of-an-mm-address-space.patch queue-4.9/s390-mm-fix-race-on-mm-context.flush_mm.patch