[kernel] r17403 - in dists/lenny/linux-2.6/debian: . patches/bugfix/x86 patches/series
Dann Frazier
dannf at alioth.debian.org
Mon May 16 00:56:58 UTC 2011
Author: dannf
Date: Mon May 16 00:56:55 2011
New Revision: 17403
Log:
[x86] mm: avoid possible bogus tlb entries by clearing prev mm_cpumask after switching mm
Added:
dists/lenny/linux-2.6/debian/patches/bugfix/x86/mm-avoid-possible-bogus-tlb-entries-by-clearing-prev-mm_cpumask-after.patch
Modified:
dists/lenny/linux-2.6/debian/changelog
dists/lenny/linux-2.6/debian/patches/series/27
Modified: dists/lenny/linux-2.6/debian/changelog
==============================================================================
--- dists/lenny/linux-2.6/debian/changelog Mon May 16 00:56:49 2011 (r17402)
+++ dists/lenny/linux-2.6/debian/changelog Mon May 16 00:56:55 2011 (r17403)
@@ -12,6 +12,8 @@
data corruption
- NFS: fix the return value of nfs_file_fsync()
- ptrace: use safer wake up on ptrace_detach()
+ - [x86] mm: avoid possible bogus tlb entries by clearing prev mm_cpumask
+ after switching mm
-- Ben Hutchings <ben at decadent.org.uk> Mon, 29 Nov 2010 02:01:24 +0000
Added: dists/lenny/linux-2.6/debian/patches/bugfix/x86/mm-avoid-possible-bogus-tlb-entries-by-clearing-prev-mm_cpumask-after.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/lenny/linux-2.6/debian/patches/bugfix/x86/mm-avoid-possible-bogus-tlb-entries-by-clearing-prev-mm_cpumask-after.patch Mon May 16 00:56:55 2011 (r17403)
@@ -0,0 +1,95 @@
+commit 999fd584fe18a07364399f8c71e13eb8aa74e054
+Author: Suresh Siddha <suresh.b.siddha at intel.com>
+Date: Thu Feb 3 12:20:04 2011 -0800
+
+ x86, mm: avoid possible bogus tlb entries by clearing prev mm_cpumask after switching mm
+
+ commit 831d52bc153971b70e64eccfbed2b232394f22f8 upstream.
+
+ Clearing the cpu in prev's mm_cpumask early will avoid the flush tlb
+ IPI's while the cr3 is still pointing to the prev mm. And this window
+ can lead to the possibility of bogus TLB fills resulting in strange
+ failures. One such problematic scenario is mentioned below.
+
+ T1. CPU-1 is context switching from mm1 to mm2 context and got a NMI
+ etc between the point of clearing the cpu from the mm_cpumask(mm1)
+ and before reloading the cr3 with the new mm2.
+
+ T2. CPU-2 is tearing down a specific vma for mm1 and will proceed with
+ flushing the TLB for mm1. It doesn't send the flush TLB to CPU-1
+ as it doesn't see that cpu listed in the mm_cpumask(mm1).
+
+ T3. After the TLB flush is complete, CPU-2 goes ahead and frees the
+ page-table pages associated with the removed vma mapping.
+
+ T4. CPU-2 now allocates those freed page-table pages for something
+ else.
+
+ T5. As the CR3 and TLB caches for mm1 is still active on CPU-1, CPU-1
+ can potentially speculate and walk through the page-table caches
+ and can insert new TLB entries. As the page-table pages are
+ already freed and being used on CPU-2, this page walk can
+ potentially insert a bogus global TLB entry depending on the
+ (random) contents of the page that is being used on CPU-2.
+
+ T6. This bogus TLB entry being global will be active across future CR3
+ changes and can result in weird memory corruption etc.
+
+ To avoid this issue, for the prev mm that is handing over the cpu to
+ another mm, clear the cpu from the mm_cpumask(prev) after the cr3 is
+ changed.
+
+ Marking it for -stable, though we haven't seen any reported failure that
+ can be attributed to this.
+
+ Signed-off-by: Suresh Siddha <suresh.b.siddha at intel.com>
+ Acked-by: Ingo Molnar <mingo at elte.hu>
+ Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+ Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+
+diff --git a/include/asm-x86/mmu_context_32.h b/include/asm-x86/mmu_context_32.h
+index 824fc57..d275232 100644
+--- a/include/asm-x86/mmu_context_32.h
++++ b/include/asm-x86/mmu_context_32.h
+@@ -17,8 +17,6 @@ static inline void switch_mm(struct mm_struct *prev,
+ int cpu = smp_processor_id();
+
+ if (likely(prev != next)) {
+- /* stop flush ipis for the previous mm */
+- cpu_clear(cpu, prev->cpu_vm_mask);
+ #ifdef CONFIG_SMP
+ per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
+ per_cpu(cpu_tlbstate, cpu).active_mm = next;
+@@ -28,6 +26,9 @@ static inline void switch_mm(struct mm_struct *prev,
+ /* Re-load page tables */
+ load_cr3(next->pgd);
+
++ /* stop flush ipis for the previous mm */
++ cpu_clear(cpu, prev->cpu_vm_mask);
++
+ /*
+ * load the LDT, if the LDT is different:
+ */
+diff --git a/include/asm-x86/mmu_context_64.h b/include/asm-x86/mmu_context_64.h
+index c700063..ffa3a24 100644
+--- a/include/asm-x86/mmu_context_64.h
++++ b/include/asm-x86/mmu_context_64.h
+@@ -16,8 +16,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+ {
+ unsigned cpu = smp_processor_id();
+ if (likely(prev != next)) {
+- /* stop flush ipis for the previous mm */
+- cpu_clear(cpu, prev->cpu_vm_mask);
+ #ifdef CONFIG_SMP
+ write_pda(mmu_state, TLBSTATE_OK);
+ write_pda(active_mm, next);
+@@ -25,6 +23,9 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+ cpu_set(cpu, next->cpu_vm_mask);
+ load_cr3(next->pgd);
+
++ /* stop flush ipis for the previous mm */
++ cpu_clear(cpu, prev->cpu_vm_mask);
++
+ if (unlikely(next->context.ldt != prev->context.ldt))
+ load_LDT_nolock(&next->context);
+ }
Modified: dists/lenny/linux-2.6/debian/patches/series/27
==============================================================================
--- dists/lenny/linux-2.6/debian/patches/series/27 Mon May 16 00:56:49 2011 (r17402)
+++ dists/lenny/linux-2.6/debian/patches/series/27 Mon May 16 00:56:55 2011 (r17403)
@@ -4,3 +4,4 @@
+ bugfix/all/fix-medium-error-problems-with-some-arrays-which-can-cause-data-corruption.patch
+ bugfix/all/nfs-fix-the-return-value-of-nfs_file_fsync.patch
+ bugfix/all/ptrace-use-safer-wake-up-on-ptrace_detach.patch
++ bugfix/x86/mm-avoid-possible-bogus-tlb-entries-by-clearing-prev-mm_cpumask-after.patch
More information about the Kernel-svn-changes
mailing list