]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 30 Dec 2017 16:38:44 +0000 (17:38 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 30 Dec 2017 16:38:44 +0000 (17:38 +0100)
added patches:
x86-mm-disable-pcid-on-32-bit-kernels.patch
x86-mm-reimplement-flush_tlb_page-using-flush_tlb_mm_range.patch
x86-mm-remove-the-up-asm-tlbflush.h-code-always-use-the-formerly-smp-code.patch

queue-4.9/series
queue-4.9/x86-mm-disable-pcid-on-32-bit-kernels.patch [new file with mode: 0644]
queue-4.9/x86-mm-reimplement-flush_tlb_page-using-flush_tlb_mm_range.patch [new file with mode: 0644]
queue-4.9/x86-mm-remove-the-up-asm-tlbflush.h-code-always-use-the-formerly-smp-code.patch [new file with mode: 0644]

index bf42dc493e0b2701a6db5047830a66fce0e7e734..feef68fd787c4d20548a3fc9a2c77d0aa402dfde 100644 (file)
@@ -13,3 +13,6 @@ alsa-hda-fix-headset-mic-detection-issue-on-a-dell-machine.patch
 x86-vm86-32-switch-to-flush_tlb_mm_range-in-mark_screen_rdonly.patch
 x86-mm-remove-flush_tlb-and-flush_tlb_current_task.patch
 x86-mm-make-flush_tlb_mm_range-more-predictable.patch
+x86-mm-reimplement-flush_tlb_page-using-flush_tlb_mm_range.patch
+x86-mm-remove-the-up-asm-tlbflush.h-code-always-use-the-formerly-smp-code.patch
+x86-mm-disable-pcid-on-32-bit-kernels.patch
diff --git a/queue-4.9/x86-mm-disable-pcid-on-32-bit-kernels.patch b/queue-4.9/x86-mm-disable-pcid-on-32-bit-kernels.patch
new file mode 100644 (file)
index 0000000..58abb0a
--- /dev/null
@@ -0,0 +1,78 @@
+From cba4671af7550e008f7a7835f06df0763825bf3e Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@kernel.org>
+Date: Thu, 29 Jun 2017 08:53:19 -0700
+Subject: x86/mm: Disable PCID on 32-bit kernels
+
+From: Andy Lutomirski <luto@kernel.org>
+
+commit cba4671af7550e008f7a7835f06df0763825bf3e upstream.
+
+32-bit kernels on new hardware will see PCID in CPUID, but PCID can
+only be used in 64-bit mode.  Rather than making all PCID code
+conditional, just disable the feature on 32-bit builds.
+
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Reviewed-by: Nadav Amit <nadav.amit@gmail.com>
+Reviewed-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Arjan van de Ven <arjan@linux.intel.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: linux-mm@kvack.org
+Link: http://lkml.kernel.org/r/2e391769192a4d31b808410c383c6bf0734bc6ea.1498751203.git.luto@kernel.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Hugh Dickins <hughd@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/disabled-features.h |    4 +++-
+ arch/x86/kernel/cpu/bugs.c               |    8 ++++++++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/include/asm/disabled-features.h
++++ b/arch/x86/include/asm/disabled-features.h
+@@ -21,11 +21,13 @@
+ # define DISABLE_K6_MTRR      (1<<(X86_FEATURE_K6_MTRR & 31))
+ # define DISABLE_CYRIX_ARR    (1<<(X86_FEATURE_CYRIX_ARR & 31))
+ # define DISABLE_CENTAUR_MCR  (1<<(X86_FEATURE_CENTAUR_MCR & 31))
++# define DISABLE_PCID         0
+ #else
+ # define DISABLE_VME          0
+ # define DISABLE_K6_MTRR      0
+ # define DISABLE_CYRIX_ARR    0
+ # define DISABLE_CENTAUR_MCR  0
++# define DISABLE_PCID         (1<<(X86_FEATURE_PCID & 31))
+ #endif /* CONFIG_X86_64 */
+ #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
+@@ -43,7 +45,7 @@
+ #define DISABLED_MASK1        0
+ #define DISABLED_MASK2        0
+ #define DISABLED_MASK3        (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR)
+-#define DISABLED_MASK4        0
++#define DISABLED_MASK4        (DISABLE_PCID)
+ #define DISABLED_MASK5        0
+ #define DISABLED_MASK6        0
+ #define DISABLED_MASK7        0
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -19,6 +19,14 @@
+ void __init check_bugs(void)
+ {
++#ifdef CONFIG_X86_32
++      /*
++       * Regardless of whether PCID is enumerated, the SDM says
++       * that it can't be enabled in 32-bit mode.
++       */
++      setup_clear_cpu_cap(X86_FEATURE_PCID);
++#endif
++
+       identify_boot_cpu();
+ #ifndef CONFIG_SMP
+       pr_info("CPU: ");
diff --git a/queue-4.9/x86-mm-reimplement-flush_tlb_page-using-flush_tlb_mm_range.patch b/queue-4.9/x86-mm-reimplement-flush_tlb_page-using-flush_tlb_mm_range.patch
new file mode 100644 (file)
index 0000000..cd27597
--- /dev/null
@@ -0,0 +1,104 @@
+From ca6c99c0794875c6d1db6e22f246699691ab7e6b Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@kernel.org>
+Date: Mon, 22 May 2017 15:30:01 -0700
+Subject: x86/mm: Reimplement flush_tlb_page() using flush_tlb_mm_range()
+
+From: Andy Lutomirski <luto@kernel.org>
+
+commit ca6c99c0794875c6d1db6e22f246699691ab7e6b upstream.
+
+flush_tlb_page() was very similar to flush_tlb_mm_range() except that
+it had a couple of issues:
+
+ - It was missing an smp_mb() in the case where
+   current->active_mm != mm.  (This is a longstanding bug reported by Nadav Amit)
+
+ - It was missing tracepoints and vm counter updates.
+
+The only reason that I can see for keeping it at as a separate
+function is that it could avoid a few branches that
+flush_tlb_mm_range() needs to decide to flush just one page.  This
+hardly seems worthwhile.  If we decide we want to get rid of those
+branches again, a better way would be to introduce an
+__flush_tlb_mm_range() helper and make both flush_tlb_page() and
+flush_tlb_mm_range() use it.
+
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Acked-by: Kees Cook <keescook@chromium.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Borislav Petkov <bpetkov@suse.de>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Nadav Amit <nadav.amit@gmail.com>
+Cc: Nadav Amit <namit@vmware.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-mm@kvack.org
+Link: http://lkml.kernel.org/r/3cc3847cf888d8907577569b8bac3f01992ef8f9.1495492063.git.luto@kernel.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Hugh Dickins <hughd@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/tlbflush.h |    6 +++++-
+ arch/x86/mm/tlb.c               |   27 ---------------------------
+ 2 files changed, 5 insertions(+), 28 deletions(-)
+
+--- a/arch/x86/include/asm/tlbflush.h
++++ b/arch/x86/include/asm/tlbflush.h
+@@ -297,11 +297,15 @@ static inline void flush_tlb_kernel_rang
+               flush_tlb_mm_range(vma->vm_mm, start, end, vma->vm_flags)
+ extern void flush_tlb_all(void);
+-extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
+ extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
+                               unsigned long end, unsigned long vmflag);
+ extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
++static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long a)
++{
++      flush_tlb_mm_range(vma->vm_mm, a, a + PAGE_SIZE, VM_NONE);
++}
++
+ void native_flush_tlb_others(const struct cpumask *cpumask,
+                               struct mm_struct *mm,
+                               unsigned long start, unsigned long end);
+--- a/arch/x86/mm/tlb.c
++++ b/arch/x86/mm/tlb.c
+@@ -354,33 +354,6 @@ out:
+       preempt_enable();
+ }
+-void flush_tlb_page(struct vm_area_struct *vma, unsigned long start)
+-{
+-      struct mm_struct *mm = vma->vm_mm;
+-
+-      preempt_disable();
+-
+-      if (current->active_mm == mm) {
+-              if (current->mm) {
+-                      /*
+-                       * Implicit full barrier (INVLPG) that synchronizes
+-                       * with switch_mm.
+-                       */
+-                      __flush_tlb_one(start);
+-              } else {
+-                      leave_mm(smp_processor_id());
+-
+-                      /* Synchronize with switch_mm. */
+-                      smp_mb();
+-              }
+-      }
+-
+-      if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids)
+-              flush_tlb_others(mm_cpumask(mm), mm, start, start + PAGE_SIZE);
+-
+-      preempt_enable();
+-}
+-
+ static void do_flush_tlb_all(void *info)
+ {
+       count_vm_tlb_event(NR_TLB_REMOTE_FLUSH_RECEIVED);
diff --git a/queue-4.9/x86-mm-remove-the-up-asm-tlbflush.h-code-always-use-the-formerly-smp-code.patch b/queue-4.9/x86-mm-remove-the-up-asm-tlbflush.h-code-always-use-the-formerly-smp-code.patch
new file mode 100644 (file)
index 0000000..8033549
--- /dev/null
@@ -0,0 +1,299 @@
+From ce4a4e565f5264909a18c733b864c3f74467f69e Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@kernel.org>
+Date: Sun, 28 May 2017 10:00:14 -0700
+Subject: x86/mm: Remove the UP asm/tlbflush.h code, always use the (formerly) SMP code
+
+From: Andy Lutomirski <luto@kernel.org>
+
+commit ce4a4e565f5264909a18c733b864c3f74467f69e upstream.
+
+The UP asm/tlbflush.h generates somewhat nicer code than the SMP version.
+Aside from that, it's fallen quite a bit behind the SMP code:
+
+ - flush_tlb_mm_range() didn't flush individual pages if the range
+   was small.
+
+ - The lazy TLB code was much weaker.  This usually wouldn't matter,
+   but, if a kernel thread flushed its lazy "active_mm" more than
+   once (due to reclaim or similar), it wouldn't be unlazied and
+   would instead pointlessly flush repeatedly.
+
+ - Tracepoints were missing.
+
+Aside from that, simply having the UP code around was a maintanence
+burden, since it means that any change to the TLB flush code had to
+make sure not to break it.
+
+Simplify everything by deleting the UP code.
+
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Arjan van de Ven <arjan@linux.intel.com>
+Cc: Borislav Petkov <bpetkov@suse.de>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Nadav Amit <nadav.amit@gmail.com>
+Cc: Nadav Amit <namit@vmware.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-mm@kvack.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Hugh Dickins <hughd@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/Kconfig                   |    2 
+ arch/x86/include/asm/hardirq.h     |    2 
+ arch/x86/include/asm/mmu.h         |    6 --
+ arch/x86/include/asm/mmu_context.h |    2 
+ arch/x86/include/asm/tlbflush.h    |   78 -------------------------------------
+ arch/x86/mm/init.c                 |    2 
+ arch/x86/mm/tlb.c                  |   17 --------
+ 7 files changed, 5 insertions(+), 104 deletions(-)
+
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -45,7 +45,7 @@ config X86
+       select ARCH_USE_CMPXCHG_LOCKREF         if X86_64
+       select ARCH_USE_QUEUED_RWLOCKS
+       select ARCH_USE_QUEUED_SPINLOCKS
+-      select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH if SMP
++      select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
+       select ARCH_WANTS_DYNAMIC_TASK_STRUCT
+       select ARCH_WANT_FRAME_POINTERS
+       select ARCH_WANT_IPC_PARSE_VERSION      if X86_32
+--- a/arch/x86/include/asm/hardirq.h
++++ b/arch/x86/include/asm/hardirq.h
+@@ -22,8 +22,8 @@ typedef struct {
+ #ifdef CONFIG_SMP
+       unsigned int irq_resched_count;
+       unsigned int irq_call_count;
+-      unsigned int irq_tlb_count;
+ #endif
++      unsigned int irq_tlb_count;
+ #ifdef CONFIG_X86_THERMAL_VECTOR
+       unsigned int irq_thermal_count;
+ #endif
+--- a/arch/x86/include/asm/mmu.h
++++ b/arch/x86/include/asm/mmu.h
+@@ -33,12 +33,6 @@ typedef struct {
+ #endif
+ } mm_context_t;
+-#ifdef CONFIG_SMP
+ void leave_mm(int cpu);
+-#else
+-static inline void leave_mm(int cpu)
+-{
+-}
+-#endif
+ #endif /* _ASM_X86_MMU_H */
+--- a/arch/x86/include/asm/mmu_context.h
++++ b/arch/x86/include/asm/mmu_context.h
+@@ -99,10 +99,8 @@ static inline void load_mm_ldt(struct mm
+ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+ {
+-#ifdef CONFIG_SMP
+       if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
+               this_cpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
+-#endif
+ }
+ static inline int init_new_context(struct task_struct *tsk,
+--- a/arch/x86/include/asm/tlbflush.h
++++ b/arch/x86/include/asm/tlbflush.h
+@@ -7,6 +7,7 @@
+ #include <asm/processor.h>
+ #include <asm/cpufeature.h>
+ #include <asm/special_insns.h>
++#include <asm/smp.h>
+ static inline void __invpcid(unsigned long pcid, unsigned long addr,
+                            unsigned long type)
+@@ -65,10 +66,8 @@ static inline void invpcid_flush_all_non
+ #endif
+ struct tlb_state {
+-#ifdef CONFIG_SMP
+       struct mm_struct *active_mm;
+       int state;
+-#endif
+       /*
+        * Access to this CR4 shadow and to H/W CR4 is protected by
+@@ -216,79 +215,6 @@ static inline void __flush_tlb_one(unsig
+  * and page-granular flushes are available only on i486 and up.
+  */
+-#ifndef CONFIG_SMP
+-
+-/* "_up" is for UniProcessor.
+- *
+- * This is a helper for other header functions.  *Not* intended to be called
+- * directly.  All global TLB flushes need to either call this, or to bump the
+- * vm statistics themselves.
+- */
+-static inline void __flush_tlb_up(void)
+-{
+-      count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
+-      __flush_tlb();
+-}
+-
+-static inline void flush_tlb_all(void)
+-{
+-      count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
+-      __flush_tlb_all();
+-}
+-
+-static inline void local_flush_tlb(void)
+-{
+-      __flush_tlb_up();
+-}
+-
+-static inline void flush_tlb_mm(struct mm_struct *mm)
+-{
+-      if (mm == current->active_mm)
+-              __flush_tlb_up();
+-}
+-
+-static inline void flush_tlb_page(struct vm_area_struct *vma,
+-                                unsigned long addr)
+-{
+-      if (vma->vm_mm == current->active_mm)
+-              __flush_tlb_one(addr);
+-}
+-
+-static inline void flush_tlb_range(struct vm_area_struct *vma,
+-                                 unsigned long start, unsigned long end)
+-{
+-      if (vma->vm_mm == current->active_mm)
+-              __flush_tlb_up();
+-}
+-
+-static inline void flush_tlb_mm_range(struct mm_struct *mm,
+-         unsigned long start, unsigned long end, unsigned long vmflag)
+-{
+-      if (mm == current->active_mm)
+-              __flush_tlb_up();
+-}
+-
+-static inline void native_flush_tlb_others(const struct cpumask *cpumask,
+-                                         struct mm_struct *mm,
+-                                         unsigned long start,
+-                                         unsigned long end)
+-{
+-}
+-
+-static inline void reset_lazy_tlbstate(void)
+-{
+-}
+-
+-static inline void flush_tlb_kernel_range(unsigned long start,
+-                                        unsigned long end)
+-{
+-      flush_tlb_all();
+-}
+-
+-#else  /* SMP */
+-
+-#include <asm/smp.h>
+-
+ #define local_flush_tlb() __flush_tlb()
+ #define flush_tlb_mm(mm)      flush_tlb_mm_range(mm, 0UL, TLB_FLUSH_ALL, 0UL)
+@@ -319,8 +245,6 @@ static inline void reset_lazy_tlbstate(v
+       this_cpu_write(cpu_tlbstate.active_mm, &init_mm);
+ }
+-#endif        /* SMP */
+-
+ #ifndef CONFIG_PARAVIRT
+ #define flush_tlb_others(mask, mm, start, end)        \
+       native_flush_tlb_others(mask, mm, start, end)
+--- a/arch/x86/mm/init.c
++++ b/arch/x86/mm/init.c
+@@ -764,10 +764,8 @@ void __init zone_sizes_init(void)
+ }
+ DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = {
+-#ifdef CONFIG_SMP
+       .active_mm = &init_mm,
+       .state = 0,
+-#endif
+       .cr4 = ~0UL,    /* fail hard if we screw up cr4 shadow initialization */
+ };
+ EXPORT_SYMBOL_GPL(cpu_tlbstate);
+--- a/arch/x86/mm/tlb.c
++++ b/arch/x86/mm/tlb.c
+@@ -15,7 +15,7 @@
+ #include <linux/debugfs.h>
+ /*
+- *    Smarter SMP flushing macros.
++ *    TLB flushing, formerly SMP-only
+  *            c/o Linus Torvalds.
+  *
+  *    These mean you can really definitely utterly forget about
+@@ -28,8 +28,6 @@
+  *    Implement flush IPI by CALL_FUNCTION_VECTOR, Alex Shi
+  */
+-#ifdef CONFIG_SMP
+-
+ struct flush_tlb_info {
+       struct mm_struct *flush_mm;
+       unsigned long flush_start;
+@@ -59,8 +57,6 @@ void leave_mm(int cpu)
+ }
+ EXPORT_SYMBOL_GPL(leave_mm);
+-#endif /* CONFIG_SMP */
+-
+ void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+              struct task_struct *tsk)
+ {
+@@ -91,10 +87,8 @@ void switch_mm_irqs_off(struct mm_struct
+                               set_pgd(pgd, init_mm.pgd[stack_pgd_index]);
+               }
+-#ifdef CONFIG_SMP
+               this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
+               this_cpu_write(cpu_tlbstate.active_mm, next);
+-#endif
+               cpumask_set_cpu(cpu, mm_cpumask(next));
+@@ -152,9 +146,7 @@ void switch_mm_irqs_off(struct mm_struct
+               if (unlikely(prev->context.ldt != next->context.ldt))
+                       load_mm_ldt(next);
+ #endif
+-      }
+-#ifdef CONFIG_SMP
+-        else {
++      } else {
+               this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
+               BUG_ON(this_cpu_read(cpu_tlbstate.active_mm) != next);
+@@ -181,11 +173,8 @@ void switch_mm_irqs_off(struct mm_struct
+                       load_mm_ldt(next);
+               }
+       }
+-#endif
+ }
+-#ifdef CONFIG_SMP
+-
+ /*
+  * The flush IPI assumes that a thread switch happens in this order:
+  * [cpu0: the cpu that switches]
+@@ -438,5 +427,3 @@ static int __init create_tlb_single_page
+       return 0;
+ }
+ late_initcall(create_tlb_single_page_flush_ceiling);
+-
+-#endif /* CONFIG_SMP */