Merge tag 'v3.10.101' into update
authorStricted <info@stricted.net>
Wed, 21 Mar 2018 21:52:41 +0000 (22:52 +0100)
committerStricted <info@stricted.net>
Wed, 21 Mar 2018 21:52:41 +0000 (22:52 +0100)
This is the 3.10.101 stable release

1  2 
Makefile
include/linux/tracepoint.h
kernel/module.c
tools/testing/selftests/efivarfs/efivarfs.sh

diff --combined Makefile
index 1cede66a6df8da1204167d912eb31a4d6b85b645,4be9e643cef000b9570492632e60d0a11900b568..4b7074f5994b508cf7427cffa5518a09ea27fd10
+++ b/Makefile
@@@ -1,6 -1,6 +1,6 @@@
  VERSION = 3
  PATCHLEVEL = 10
- SUBLEVEL = 100
+ SUBLEVEL = 101
  EXTRAVERSION =
  NAME = TOSSUG Baby Fish
  
@@@ -374,7 -374,7 +374,7 @@@ KBUILD_CFLAGS   := -Wall -Wundef -Wstri
                   -Werror-implicit-function-declaration \
                   -Wno-format-security \
                   -fno-delete-null-pointer-checks \
 -                 -std=gnu89
 +                 -w -std=gnu89
  
  KBUILD_AFLAGS_KERNEL :=
  KBUILD_CFLAGS_KERNEL :=
index 1faa423724c874be32dcf9b348f16870436dfb0b,36e5e9998865182f48db41277751426a731f9eb2..fe6f0b3fe49c75cc56e3560bbcee18325b55ae43
@@@ -129,9 -129,6 +129,6 @@@ static inline void tracepoint_synchroni
                void *it_func;                                          \
                void *__data;                                           \
                                                                        \
-               if (!cpu_online(raw_smp_processor_id()))                \
-                       return;                                         \
-                                                                       \
                if (!(cond))                                            \
                        return;                                         \
                prercu;                                                 \
  
  #endif /* CONFIG_TRACEPOINTS */
  
 +#ifdef CONFIG_TRACING
 +/**
 + * tracepoint_string - register constant persistent string to trace system
 + * @str - a constant persistent string that will be referenced in tracepoints
 + *
 + * If constant strings are being used in tracepoints, it is faster and
 + * more efficient to just save the pointer to the string and reference
 + * that with a printf "%s" instead of saving the string in the ring buffer
 + * and wasting space and time.
 + *
 + * The problem with the above approach is that userspace tools that read
 + * the binary output of the trace buffers do not have access to the string.
 + * Instead they just show the address of the string which is not very
 + * useful to users.
 + *
 + * With tracepoint_string(), the string will be registered to the tracing
 + * system and exported to userspace via the debugfs/tracing/printk_formats
 + * file that maps the string address to the string text. This way userspace
 + * tools that read the binary buffers have a way to map the pointers to
 + * the ASCII strings they represent.
 + *
 + * The @str used must be a constant string and persistent as it would not
 + * make sense to show a string that no longer exists. But it is still fine
 + * to be used with modules, because when modules are unloaded, if they
 + * had tracepoints, the ring buffers are cleared too. As long as the string
 + * does not change during the life of the module, it is fine to use
 + * tracepoint_string() within a module.
 + */
 +#define tracepoint_string(str)                                                \
 +      ({                                                              \
 +              static const char *___tp_str __tracepoint_string = str; \
 +              ___tp_str;                                              \
 +      })
 +#define __tracepoint_string   __attribute__((section("__tracepoint_str")))
 +#else
 +/*
 + * tracepoint_string() is used to save the string address for userspace
 + * tracing tools. When tracing isn't configured, there's no need to save
 + * anything.
 + */
 +# define tracepoint_string(str) str
 +# define __tracepoint_string
 +#endif
 +
  /*
   * The need for the DECLARE_TRACE_NOARGS() is to handle the prototype
   * (void). "void" is a special value in a function prototype and can
   * "void *__data, proto" as the callback prototype.
   */
  #define DECLARE_TRACE_NOARGS(name)                                    \
-               __DECLARE_TRACE(name, void, , 1, void *__data, __data)
+       __DECLARE_TRACE(name, void, ,                                   \
+                       cpu_online(raw_smp_processor_id()),             \
+                       void *__data, __data)
  
  #define DECLARE_TRACE(name, proto, args)                              \
-               __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), 1,   \
-                               PARAMS(void *__data, proto),            \
-                               PARAMS(__data, args))
+       __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),              \
+                       cpu_online(raw_smp_processor_id()),             \
+                       PARAMS(void *__data, proto),                    \
+                       PARAMS(__data, args))
  
  #define DECLARE_TRACE_CONDITION(name, proto, args, cond)              \
-       __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), PARAMS(cond), \
+       __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),              \
+                       cpu_online(raw_smp_processor_id()) && (PARAMS(cond)), \
                        PARAMS(void *__data, proto),                    \
                        PARAMS(__data, args))
  
diff --combined kernel/module.c
index 57085deed9937087f35a4346e4d8dcad010e9e87,f8a4f48b48a9efbfb363d38588971c96da133af7..d50d899b026cf121c2bd2c2162a6f3dc92956bd8
@@@ -179,6 -179,9 +179,9 @@@ struct load_info 
        struct _ddebug *debug;
        unsigned int num_debug;
        bool sig_ok;
+ #ifdef CONFIG_KALLSYMS
+       unsigned long mod_kallsyms_init_off;
+ #endif
        struct {
                unsigned int sym, str, mod, vers, info, pcpu;
        } index;
@@@ -2346,8 -2349,20 +2349,20 @@@ static void layout_symtab(struct modul
        strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect,
                                         info->index.str) | INIT_OFFSET_MASK;
        pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
+       /* We'll tack temporary mod_kallsyms on the end. */
+       mod->init_size = ALIGN(mod->init_size,
+                              __alignof__(struct mod_kallsyms));
+       info->mod_kallsyms_init_off = mod->init_size;
+       mod->init_size += sizeof(struct mod_kallsyms);
+       mod->init_size = debug_align(mod->init_size);
  }
  
+ /*
+  * We use the full symtab and strtab which layout_symtab arranged to
+  * be appended to the init section.  Later we switch to the cut-down
+  * core-only ones.
+  */
  static void add_kallsyms(struct module *mod, const struct load_info *info)
  {
        unsigned int i, ndst;
        char *s;
        Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
  
-       mod->symtab = (void *)symsec->sh_addr;
-       mod->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
+       /* Set up to point into init section. */
+       mod->kallsyms = mod->module_init + info->mod_kallsyms_init_off;
+       mod->kallsyms->symtab = (void *)symsec->sh_addr;
+       mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
        /* Make sure we get permanent strtab: don't use info->strtab. */
-       mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
+       mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
  
        /* Set types up while we still have access to sections. */
-       for (i = 0; i < mod->num_symtab; i++)
-               mod->symtab[i].st_info = elf_type(&mod->symtab[i], info);
-       mod->core_symtab = dst = mod->module_core + info->symoffs;
-       mod->core_strtab = s = mod->module_core + info->stroffs;
-       src = mod->symtab;
-       for (ndst = i = 0; i < mod->num_symtab; i++) {
+       for (i = 0; i < mod->kallsyms->num_symtab; i++)
+               mod->kallsyms->symtab[i].st_info
+                       = elf_type(&mod->kallsyms->symtab[i], info);
+       /* Now populate the cut down core kallsyms for after init. */
+       mod->core_kallsyms.symtab = dst = mod->module_core + info->symoffs;
+       mod->core_kallsyms.strtab = s = mod->module_core + info->stroffs;
+       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)) {
                        dst[ndst] = src[i];
-                       dst[ndst++].st_name = s - mod->core_strtab;
-                       s += strlcpy(s, &mod->strtab[src[i].st_name],
+                       dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
+                       s += strlcpy(s, &mod->kallsyms->strtab[src[i].st_name],
                                     KSYM_NAME_LEN) + 1;
                }
        }
-       mod->core_num_syms = ndst;
+       mod->core_kallsyms.num_symtab = ndst;
  }
  #else
  static inline void layout_symtab(struct module *mod, struct load_info *info)
@@@ -3117,9 -3137,8 +3137,8 @@@ static int do_init_module(struct modul
        module_put(mod);
        trim_init_extable(mod);
  #ifdef CONFIG_KALLSYMS
-       mod->num_symtab = mod->core_num_syms;
-       mod->symtab = mod->core_symtab;
-       mod->strtab = mod->core_strtab;
+       /* Switch to core kallsyms now init is done: kallsyms may be walking! */
+       rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms);
  #endif
        unset_module_init_ro_nx(mod);
        module_free(mod, mod->module_init);
@@@ -3398,9 -3417,9 +3417,9 @@@ static inline int is_arm_mapping_symbol
               && (str[2] == '\0' || str[2] == '.');
  }
  
- static const char *symname(struct module *mod, unsigned int symnum)
+ static const char *symname(struct mod_kallsyms *kallsyms, unsigned int symnum)
  {
-       return mod->strtab + mod->symtab[symnum].st_name;
+       return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
  }
  
  static const char *get_ksymbol(struct module *mod,
  {
        unsigned int i, best = 0;
        unsigned long nextval;
+       struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
  
        /* At worse, next value is at end of module */
        if (within_module_init(addr, mod))
  
        /* Scan for closest preceding symbol, and next symbol. (ELF
           starts real symbols at 1). */
-       for (i = 1; i < mod->num_symtab; i++) {
-               if (mod->symtab[i].st_shndx == SHN_UNDEF)
+       for (i = 1; i < kallsyms->num_symtab; i++) {
+               if (kallsyms->symtab[i].st_shndx == SHN_UNDEF)
                        continue;
  
                /* We ignore unnamed symbols: they're uninformative
                 * and inserted at a whim. */
-               if (*symname(mod, i) == '\0'
-                   || is_arm_mapping_symbol(symname(mod, i)))
+               if (*symname(kallsyms, i) == '\0'
+                   || is_arm_mapping_symbol(symname(kallsyms, i)))
                        continue;
  
-               if (mod->symtab[i].st_value <= addr
-                   && mod->symtab[i].st_value > mod->symtab[best].st_value)
+               if (kallsyms->symtab[i].st_value <= addr
+                   && kallsyms->symtab[i].st_value > kallsyms->symtab[best].st_value)
                        best = i;
-               if (mod->symtab[i].st_value > addr
-                   && mod->symtab[i].st_value < nextval)
-                       nextval = mod->symtab[i].st_value;
+               if (kallsyms->symtab[i].st_value > addr
+                   && kallsyms->symtab[i].st_value < nextval)
+                       nextval = kallsyms->symtab[i].st_value;
        }
  
        if (!best)
                return NULL;
  
        if (size)
-               *size = nextval - mod->symtab[best].st_value;
+               *size = nextval - kallsyms->symtab[best].st_value;
        if (offset)
-               *offset = addr - mod->symtab[best].st_value;
-       return symname(mod, best);
+               *offset = addr - kallsyms->symtab[best].st_value;
+       return symname(kallsyms, best);
  }
  
  /* For kallsyms to ask for address resolution.  NULL means not found.  Careful
@@@ -3540,18 -3560,21 +3560,21 @@@ int module_get_kallsym(unsigned int sym
  
        preempt_disable();
        list_for_each_entry_rcu(mod, &modules, list) {
+               struct mod_kallsyms *kallsyms;
                if (mod->state == MODULE_STATE_UNFORMED)
                        continue;
-               if (symnum < mod->num_symtab) {
-                       *value = mod->symtab[symnum].st_value;
-                       *type = mod->symtab[symnum].st_info;
-                       strlcpy(name, symname(mod, symnum), KSYM_NAME_LEN);
+               kallsyms = rcu_dereference_sched(mod->kallsyms);
+               if (symnum < kallsyms->num_symtab) {
+                       *value = kallsyms->symtab[symnum].st_value;
+                       *type = kallsyms->symtab[symnum].st_info;
+                       strlcpy(name, symname(kallsyms, symnum), KSYM_NAME_LEN);
                        strlcpy(module_name, mod->name, MODULE_NAME_LEN);
                        *exported = is_exported(name, *value, mod);
                        preempt_enable();
                        return 0;
                }
-               symnum -= mod->num_symtab;
+               symnum -= kallsyms->num_symtab;
        }
        preempt_enable();
        return -ERANGE;
  static unsigned long mod_find_symname(struct module *mod, const char *name)
  {
        unsigned int i;
+       struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
  
-       for (i = 0; i < mod->num_symtab; i++)
-               if (strcmp(name, symname(mod, i)) == 0 &&
-                   mod->symtab[i].st_info != 'U')
-                       return mod->symtab[i].st_value;
+       for (i = 0; i < kallsyms->num_symtab; i++)
+               if (strcmp(name, symname(kallsyms, i)) == 0 &&
+                   kallsyms->symtab[i].st_info != 'U')
+                       return kallsyms->symtab[i].st_value;
        return 0;
  }
  
@@@ -3603,11 -3627,14 +3627,14 @@@ int module_kallsyms_on_each_symbol(int 
        int ret;
  
        list_for_each_entry(mod, &modules, list) {
+               /* We hold module_mutex: no need for rcu_dereference_sched */
+               struct mod_kallsyms *kallsyms = mod->kallsyms;
                if (mod->state == MODULE_STATE_UNFORMED)
                        continue;
-               for (i = 0; i < mod->num_symtab; i++) {
-                       ret = fn(data, symname(mod, i),
-                                mod, mod->symtab[i].st_value);
+               for (i = 0; i < kallsyms->num_symtab; i++) {
+                       ret = fn(data, symname(kallsyms, i),
+                                mod, kallsyms->symtab[i].st_value);
                        if (ret != 0)
                                return ret;
                }
@@@ -3838,7 -3865,7 +3865,7 @@@ void print_modules(void
        list_for_each_entry_rcu(mod, &modules, list) {
                if (mod->state == MODULE_STATE_UNFORMED)
                        continue;
 -              printk(" %s%s", mod->name, module_flags(mod, buf));
 +              printk(" %s %p %s", mod->name, mod->module_core,  module_flags(mod, buf));
        }
        preempt_enable();
        if (last_unloaded_module[0])
index 77edcdcc016bbe9e891dbee8ce27c5824caaae63,057278448515a455a17ff2b48af2bf0902c2e7fb..057278448515a455a17ff2b48af2bf0902c2e7fb
mode 100755,100644..100755
@@@ -88,7 -88,11 +88,11 @@@ test_delete(
                exit 1
        fi
  
-       rm $file
+       rm $file 2>/dev/null
+       if [ $? -ne 0 ]; then
+               chattr -i $file
+               rm $file
+       fi
  
        if [ -e $file ]; then
                echo "$file couldn't be deleted" >&2
@@@ -111,6 -115,7 +115,7 @@@ test_zero_size_delete(
                exit 1
        fi
  
+       chattr -i $file
        printf "$attrs" > $file
  
        if [ -e $file ]; then
@@@ -141,7 -146,11 +146,11 @@@ test_valid_filenames(
                        echo "$file could not be created" >&2
                        ret=1
                else
-                       rm $file
+                       rm $file 2>/dev/null
+                       if [ $? -ne 0 ]; then
+                               chattr -i $file
+                               rm $file
+                       fi
                fi
        done
  
@@@ -174,7 -183,11 +183,11 @@@ test_invalid_filenames(
  
                if [ -e $file ]; then
                        echo "Creating $file should have failed" >&2
-                       rm $file
+                       rm $file 2>/dev/null
+                       if [ $? -ne 0 ]; then
+                               chattr -i $file
+                               rm $file
+                       fi
                        ret=1
                fi
        done