]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 8 Jan 2018 12:52:54 +0000 (13:52 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 8 Jan 2018 12:52:54 +0000 (13:52 +0100)
added patches:
genksyms-handle-string-literals-with-spaces-in-reference-files.patch
map-the-vsyscall-page-with-_page_user.patch
module-issue-warnings-when-tainting-kernel.patch
module-keep-percpu-symbols-in-module-s-symtab.patch
proc-much-faster-proc-vmstat.patch

queue-4.4/genksyms-handle-string-literals-with-spaces-in-reference-files.patch [new file with mode: 0644]
queue-4.4/map-the-vsyscall-page-with-_page_user.patch [new file with mode: 0644]
queue-4.4/module-issue-warnings-when-tainting-kernel.patch [new file with mode: 0644]
queue-4.4/module-keep-percpu-symbols-in-module-s-symtab.patch [new file with mode: 0644]
queue-4.4/proc-much-faster-proc-vmstat.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/genksyms-handle-string-literals-with-spaces-in-reference-files.patch b/queue-4.4/genksyms-handle-string-literals-with-spaces-in-reference-files.patch
new file mode 100644 (file)
index 0000000..413c119
--- /dev/null
@@ -0,0 +1,45 @@
+From a78f70e8d65e88b9f631d073f68cb26dcd746298 Mon Sep 17 00:00:00 2001
+From: Michal Marek <mmarek@suse.com>
+Date: Wed, 9 Dec 2015 15:08:21 +0100
+Subject: genksyms: Handle string literals with spaces in reference files
+
+From: Michal Marek <mmarek@suse.com>
+
+commit a78f70e8d65e88b9f631d073f68cb26dcd746298 upstream.
+
+The reference files use spaces to separate tokens, however, we must
+preserve spaces inside string literals. Currently the only case in the
+tree is struct edac_raw_error_desc in <linux/edac.h>:
+
+$ KBUILD_SYMTYPES=1 make -s drivers/edac/amd64_edac.symtypes
+$ mv drivers/edac/amd64_edac.{symtypes,symref}
+$ KBUILD_SYMTYPES=1 make -s drivers/edac/amd64_edac.symtypes
+drivers/edac/amd64_edac.c:527: warning: amd64_get_dram_hole_info: modversion changed because of changes in struct edac_raw_error_desc
+
+Signed-off-by: Michal Marek <mmarek@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ scripts/genksyms/genksyms.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/scripts/genksyms/genksyms.c
++++ b/scripts/genksyms/genksyms.c
+@@ -423,13 +423,15 @@ static struct string_list *read_node(FIL
+       struct string_list node = {
+               .string = buffer,
+               .tag = SYM_NORMAL };
+-      int c;
++      int c, in_string = 0;
+       while ((c = fgetc(f)) != EOF) {
+-              if (c == ' ') {
++              if (!in_string && c == ' ') {
+                       if (node.string == buffer)
+                               continue;
+                       break;
++              } else if (c == '"') {
++                      in_string = !in_string;
+               } else if (c == '\n') {
+                       if (node.string == buffer)
+                               return NULL;
diff --git a/queue-4.4/map-the-vsyscall-page-with-_page_user.patch b/queue-4.4/map-the-vsyscall-page-with-_page_user.patch
new file mode 100644 (file)
index 0000000..f032ddf
--- /dev/null
@@ -0,0 +1,143 @@
+From: Borislav Petkov <bp@suse.de>
+Date: Thu, 4 Jan 2018 17:42:45 +0100
+Subject: Map the vsyscall page with _PAGE_USER
+
+From: Borislav Petkov <bp@suse.de>
+
+This needs to happen early in kaiser_pagetable_walk(), before the
+hierarchy is established so that _PAGE_USER permission can be really
+set.
+
+A proper fix would be to teach kaiser_pagetable_walk() to update those
+permissions but the vsyscall page is the only exception here so ...
+
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/entry/vsyscall/vsyscall_64.c |    5 +++++
+ arch/x86/include/asm/vsyscall.h       |    2 ++
+ arch/x86/mm/kaiser.c                  |   34 ++++++++++++++++++++++++++++++----
+ 3 files changed, 37 insertions(+), 4 deletions(-)
+
+--- a/arch/x86/entry/vsyscall/vsyscall_64.c
++++ b/arch/x86/entry/vsyscall/vsyscall_64.c
+@@ -66,6 +66,11 @@ static int __init vsyscall_setup(char *s
+ }
+ early_param("vsyscall", vsyscall_setup);
++bool vsyscall_enabled(void)
++{
++      return vsyscall_mode != NONE;
++}
++
+ static void warn_bad_vsyscall(const char *level, struct pt_regs *regs,
+                             const char *message)
+ {
+--- a/arch/x86/include/asm/vsyscall.h
++++ b/arch/x86/include/asm/vsyscall.h
+@@ -12,12 +12,14 @@ extern void map_vsyscall(void);
+  * Returns true if handled.
+  */
+ extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address);
++extern bool vsyscall_enabled(void);
+ #else
+ static inline void map_vsyscall(void) {}
+ static inline bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
+ {
+       return false;
+ }
++bool vsyscall_enabled(void) { return false; }
+ #endif
+ #endif /* _ASM_X86_VSYSCALL_H */
+--- a/arch/x86/mm/kaiser.c
++++ b/arch/x86/mm/kaiser.c
+@@ -20,6 +20,7 @@
+ #include <asm/pgalloc.h>
+ #include <asm/desc.h>
+ #include <asm/cmdline.h>
++#include <asm/vsyscall.h>
+ int kaiser_enabled __read_mostly = 1;
+ EXPORT_SYMBOL(kaiser_enabled);        /* for inlined TLB flush functions */
+@@ -111,12 +112,13 @@ static inline unsigned long get_pa_from_
+  *
+  * Returns a pointer to a PTE on success, or NULL on failure.
+  */
+-static pte_t *kaiser_pagetable_walk(unsigned long address)
++static pte_t *kaiser_pagetable_walk(unsigned long address, bool user)
+ {
+       pmd_t *pmd;
+       pud_t *pud;
+       pgd_t *pgd = native_get_shadow_pgd(pgd_offset_k(address));
+       gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO);
++      unsigned long prot = _KERNPG_TABLE;
+       if (pgd_none(*pgd)) {
+               WARN_ONCE(1, "All shadow pgds should have been populated");
+@@ -124,6 +126,17 @@ static pte_t *kaiser_pagetable_walk(unsi
+       }
+       BUILD_BUG_ON(pgd_large(*pgd) != 0);
++      if (user) {
++              /*
++               * The vsyscall page is the only page that will have
++               *  _PAGE_USER set. Catch everything else.
++               */
++              BUG_ON(address != VSYSCALL_ADDR);
++
++              set_pgd(pgd, __pgd(pgd_val(*pgd) | _PAGE_USER));
++              prot = _PAGE_TABLE;
++      }
++
+       pud = pud_offset(pgd, address);
+       /* The shadow page tables do not use large mappings: */
+       if (pud_large(*pud)) {
+@@ -136,7 +149,7 @@ static pte_t *kaiser_pagetable_walk(unsi
+                       return NULL;
+               spin_lock(&shadow_table_allocation_lock);
+               if (pud_none(*pud)) {
+-                      set_pud(pud, __pud(_KERNPG_TABLE | __pa(new_pmd_page)));
++                      set_pud(pud, __pud(prot | __pa(new_pmd_page)));
+                       __inc_zone_page_state(virt_to_page((void *)
+                                               new_pmd_page), NR_KAISERTABLE);
+               } else
+@@ -156,7 +169,7 @@ static pte_t *kaiser_pagetable_walk(unsi
+                       return NULL;
+               spin_lock(&shadow_table_allocation_lock);
+               if (pmd_none(*pmd)) {
+-                      set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(new_pte_page)));
++                      set_pmd(pmd, __pmd(prot | __pa(new_pte_page)));
+                       __inc_zone_page_state(virt_to_page((void *)
+                                               new_pte_page), NR_KAISERTABLE);
+               } else
+@@ -192,7 +205,7 @@ static int kaiser_add_user_map(const voi
+                       ret = -EIO;
+                       break;
+               }
+-              pte = kaiser_pagetable_walk(address);
++              pte = kaiser_pagetable_walk(address, flags & _PAGE_USER);
+               if (!pte) {
+                       ret = -ENOMEM;
+                       break;
+@@ -319,6 +332,19 @@ void __init kaiser_init(void)
+       kaiser_init_all_pgds();
++      /*
++       * Note that this sets _PAGE_USER and it needs to happen when the
++       * pagetable hierarchy gets created, i.e., early. Otherwise
++       * kaiser_pagetable_walk() will encounter initialized PTEs in the
++       * hierarchy and not set the proper permissions, leading to the
++       * pagefaults with page-protection violations when trying to read the
++       * vsyscall page. For example.
++       */
++      if (vsyscall_enabled())
++              kaiser_add_user_map_early((void *)VSYSCALL_ADDR,
++                                        PAGE_SIZE,
++                                         __PAGE_KERNEL_VSYSCALL);
++
+       for_each_possible_cpu(cpu) {
+               void *percpu_vaddr = __per_cpu_user_mapped_start +
+                                    per_cpu_offset(cpu);
diff --git a/queue-4.4/module-issue-warnings-when-tainting-kernel.patch b/queue-4.4/module-issue-warnings-when-tainting-kernel.patch
new file mode 100644 (file)
index 0000000..42452fe
--- /dev/null
@@ -0,0 +1,57 @@
+From 3205c36cf7d96024626f92d65f560035df1abcb2 Mon Sep 17 00:00:00 2001
+From: Libor Pechacek <lpechacek@suse.com>
+Date: Wed, 13 Apr 2016 11:06:12 +0930
+Subject: module: Issue warnings when tainting kernel
+
+From: Libor Pechacek <lpechacek@suse.com>
+
+commit 3205c36cf7d96024626f92d65f560035df1abcb2 upstream.
+
+While most of the locations where a kernel taint bit is set are accompanied
+with a warning message, there are two which set their bits silently.  If
+the tainting module gets unloaded later on, it is almost impossible to tell
+what was the reason for setting the flag.
+
+Signed-off-by: Libor Pechacek <lpechacek@suse.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/module.c |   11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -2888,8 +2888,12 @@ static int check_modinfo(struct module *
+               return -ENOEXEC;
+       }
+-      if (!get_modinfo(info, "intree"))
++      if (!get_modinfo(info, "intree")) {
++              if (!test_taint(TAINT_OOT_MODULE))
++                      pr_warn("%s: loading out-of-tree module taints kernel.\n",
++                              mod->name);
+               add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
++      }
+       if (get_modinfo(info, "staging")) {
+               add_taint_module(mod, TAINT_CRAP, LOCKDEP_STILL_OK);
+@@ -3054,6 +3058,8 @@ static int move_module(struct module *mo
+ static int check_module_license_and_versions(struct module *mod)
+ {
++      int prev_taint = test_taint(TAINT_PROPRIETARY_MODULE);
++
+       /*
+        * ndiswrapper is under GPL by itself, but loads proprietary modules.
+        * Don't use add_taint_module(), as it would prevent ndiswrapper from
+@@ -3072,6 +3078,9 @@ static int check_module_license_and_vers
+               add_taint_module(mod, TAINT_PROPRIETARY_MODULE,
+                                LOCKDEP_NOW_UNRELIABLE);
++      if (!prev_taint && test_taint(TAINT_PROPRIETARY_MODULE))
++              pr_warn("%s: module license taints kernel.\n", mod->name);
++
+ #ifdef CONFIG_MODVERSIONS
+       if ((mod->num_syms && !mod->crcs)
+           || (mod->num_gpl_syms && !mod->gpl_crcs)
diff --git a/queue-4.4/module-keep-percpu-symbols-in-module-s-symtab.patch b/queue-4.4/module-keep-percpu-symbols-in-module-s-symtab.patch
new file mode 100644 (file)
index 0000000..d98e007
--- /dev/null
@@ -0,0 +1,90 @@
+From e0224418516b4d8a6c2160574bac18447c354ef0 Mon Sep 17 00:00:00 2001
+From: Miroslav Benes <mbenes@suse.cz>
+Date: Thu, 26 Nov 2015 13:18:06 +1030
+Subject: module: keep percpu symbols in module's symtab
+
+From: Miroslav Benes <mbenes@suse.cz>
+
+commit e0224418516b4d8a6c2160574bac18447c354ef0 upstream.
+
+Currently, percpu symbols from .data..percpu ELF section of a module are
+not copied over and stored in final symtab array of struct module.
+Consequently such symbol cannot be returned via kallsyms API (for
+example kallsyms_lookup_name). This can be especially confusing when the
+percpu symbol is exported. Only its __ksymtab et al. are present in its
+symtab.
+
+The culprit is in layout_and_allocate() function where SHF_ALLOC flag is
+dropped for .data..percpu section. There is in fact no need to copy the
+section to final struct module, because kernel module loader allocates
+extra percpu section by itself. Unfortunately only symbols from
+SHF_ALLOC sections are copied due to a check in is_core_symbol().
+
+The patch changes is_core_symbol() function to copy over also percpu
+symbols (their st_shndx points to .data..percpu ELF section). We do it
+only if CONFIG_KALLSYMS_ALL is set to be consistent with the rest of the
+function (ELF section is SHF_ALLOC but !SHF_EXECINSTR). Finally
+elf_type() returns type 'a' for a percpu symbol because its address is
+absolute.
+
+Signed-off-by: Miroslav Benes <mbenes@suse.cz>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/module.c |   15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -2404,7 +2404,7 @@ static char elf_type(const Elf_Sym *sym,
+       }
+       if (sym->st_shndx == SHN_UNDEF)
+               return 'U';
+-      if (sym->st_shndx == SHN_ABS)
++      if (sym->st_shndx == SHN_ABS || sym->st_shndx == info->index.pcpu)
+               return 'a';
+       if (sym->st_shndx >= SHN_LORESERVE)
+               return '?';
+@@ -2433,7 +2433,7 @@ static char elf_type(const Elf_Sym *sym,
+ }
+ static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
+-                      unsigned int shnum)
++                      unsigned int shnum, unsigned int pcpundx)
+ {
+       const Elf_Shdr *sec;
+@@ -2442,6 +2442,11 @@ static bool is_core_symbol(const Elf_Sym
+           || !src->st_name)
+               return false;
++#ifdef CONFIG_KALLSYMS_ALL
++      if (src->st_shndx == pcpundx)
++              return true;
++#endif
++
+       sec = sechdrs + src->st_shndx;
+       if (!(sec->sh_flags & SHF_ALLOC)
+ #ifndef CONFIG_KALLSYMS_ALL
+@@ -2479,7 +2484,8 @@ static void layout_symtab(struct module
+       /* Compute total space required for the core symbols' strtab. */
+       for (ndst = i = 0; i < nsrc; i++) {
+               if (i == 0 ||
+-                  is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
++                  is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum,
++                                 info->index.pcpu)) {
+                       strtab_size += strlen(&info->strtab[src[i].st_name])+1;
+                       ndst++;
+               }
+@@ -2537,7 +2543,8 @@ static void add_kallsyms(struct module *
+       src = mod->kallsyms->symtab;
+       for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) {
+               if (i == 0 ||
+-                  is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
++                  is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum,
++                                 info->index.pcpu)) {
+                       dst[ndst] = src[i];
+                       dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
+                       s += strlcpy(s, &mod->kallsyms->strtab[src[i].st_name],
diff --git a/queue-4.4/proc-much-faster-proc-vmstat.patch b/queue-4.4/proc-much-faster-proc-vmstat.patch
new file mode 100644 (file)
index 0000000..8846f47
--- /dev/null
@@ -0,0 +1,103 @@
+From 68ba0326b4e14988f9e0c24a6e12a85cf2acd1ca Mon Sep 17 00:00:00 2001
+From: Alexey Dobriyan <adobriyan@gmail.com>
+Date: Fri, 7 Oct 2016 17:02:14 -0700
+Subject: proc: much faster /proc/vmstat
+
+From: Alexey Dobriyan <adobriyan@gmail.com>
+
+commit 68ba0326b4e14988f9e0c24a6e12a85cf2acd1ca upstream.
+
+Every current KDE system has process named ksysguardd polling files
+below once in several seconds:
+
+       $ strace -e trace=open -p $(pidof ksysguardd)
+       Process 1812 attached
+       open("/etc/mtab", O_RDONLY|O_CLOEXEC)   = 8
+       open("/etc/mtab", O_RDONLY|O_CLOEXEC)   = 8
+       open("/proc/net/dev", O_RDONLY)         = 8
+       open("/proc/net/wireless", O_RDONLY)    = -1 ENOENT (No such file or directory)
+       open("/proc/stat", O_RDONLY)            = 8
+       open("/proc/vmstat", O_RDONLY)          = 8
+
+Hell knows what it is doing but speed up reading /proc/vmstat by 33%!
+
+Benchmark is open+read+close 1.000.000 times.
+
+                       BEFORE
+$ perf stat -r 10 taskset -c 3 ./proc-vmstat
+
+ Performance counter stats for 'taskset -c 3 ./proc-vmstat' (10 runs):
+
+      13146.768464      task-clock (msec)         #    0.960 CPUs utilized            ( +-  0.60% )
+                15      context-switches          #    0.001 K/sec                    ( +-  1.41% )
+                 1      cpu-migrations            #    0.000 K/sec                    ( +- 11.11% )
+               104      page-faults               #    0.008 K/sec                    ( +-  0.57% )
+    45,489,799,349      cycles                    #    3.460 GHz                      ( +-  0.03% )
+     9,970,175,743      stalled-cycles-frontend   #   21.92% frontend cycles idle     ( +-  0.10% )
+     2,800,298,015      stalled-cycles-backend    #   6.16% backend cycles idle       ( +-  0.32% )
+    79,241,190,850      instructions              #    1.74  insn per cycle
+                                                  #    0.13  stalled cycles per insn  ( +-  0.00% )
+    17,616,096,146      branches                  # 1339.956 M/sec                    ( +-  0.00% )
+       176,106,232      branch-misses             #    1.00% of all branches          ( +-  0.18% )
+
+      13.691078109 seconds time elapsed                                          ( +-  0.03% )
+      ^^^^^^^^^^^^
+
+                       AFTER
+$ perf stat -r 10 taskset -c 3 ./proc-vmstat
+
+ Performance counter stats for 'taskset -c 3 ./proc-vmstat' (10 runs):
+
+       8688.353749      task-clock (msec)         #    0.950 CPUs utilized            ( +-  1.25% )
+                10      context-switches          #    0.001 K/sec                    ( +-  2.13% )
+                 1      cpu-migrations            #    0.000 K/sec
+               104      page-faults               #    0.012 K/sec                    ( +-  0.56% )
+    30,384,010,730      cycles                    #    3.497 GHz                      ( +-  0.07% )
+    12,296,259,407      stalled-cycles-frontend   #   40.47% frontend cycles idle     ( +-  0.13% )
+     3,370,668,651      stalled-cycles-backend    #  11.09% backend cycles idle       ( +-  0.69% )
+    28,969,052,879      instructions              #    0.95  insn per cycle
+                                                  #    0.42  stalled cycles per insn  ( +-  0.01% )
+     6,308,245,891      branches                  #  726.058 M/sec                    ( +-  0.00% )
+       214,685,502      branch-misses             #    3.40% of all branches          ( +-  0.26% )
+
+       9.146081052 seconds time elapsed                                          ( +-  0.07% )
+       ^^^^^^^^^^^
+
+vsnprintf() is slow because:
+
+1. format_decode() is busy looking for format specifier: 2 branches
+   per character (not in this case, but in others)
+
+2. approximately million branches while parsing format mini language
+   and everywhere
+
+3.  just look at what string() does /proc/vmstat is good case because
+   most of its content are strings
+
+Link: http://lkml.kernel.org/r/20160806125455.GA1187@p183.telecom.by
+Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
+Cc: Joe Perches <joe@perches.com>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Mel Gorman <mgorman@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/vmstat.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/mm/vmstat.c
++++ b/mm/vmstat.c
+@@ -1351,7 +1351,9 @@ static int vmstat_show(struct seq_file *
+       unsigned long *l = arg;
+       unsigned long off = l - (unsigned long *)m->private;
+-      seq_printf(m, "%s %lu\n", vmstat_text[off], *l);
++      seq_puts(m, vmstat_text[off]);
++      seq_put_decimal_ull(m, ' ', *l);
++      seq_putc(m, '\n');
+       return 0;
+ }
index 5420fdbc808b0d931689b1efb25afea1b2ab85ba..333e819fcc03ed66b8146e1ec8ab0dc9fbac205c 100644 (file)
@@ -15,3 +15,8 @@ x86-microcode-amd-add-support-for-fam17h-microcode-loading.patch
 parisc-fix-alignment-of-pa_tlb_lock-in-assembly-on-32-bit-smp-kernel.patch
 mtd-nand-pxa3xx-fix-readoob-implementation.patch
 x86-tlb-drop-the-_gpl-from-the-cpu_tlbstate-export.patch
+genksyms-handle-string-literals-with-spaces-in-reference-files.patch
+module-keep-percpu-symbols-in-module-s-symtab.patch
+module-issue-warnings-when-tainting-kernel.patch
+proc-much-faster-proc-vmstat.patch
+map-the-vsyscall-page-with-_page_user.patch