]> Git Repo - linux.git/commitdiff
Merge tag 'modules-for-v4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu...
authorLinus Torvalds <[email protected]>
Thu, 15 Dec 2016 04:12:43 +0000 (20:12 -0800)
committerLinus Torvalds <[email protected]>
Thu, 15 Dec 2016 04:12:43 +0000 (20:12 -0800)
Pull modules updates from Jessica Yu:
 "Summary of modules changes for the 4.10 merge window:

   - The rodata= cmdline parameter has been extended to additionally
     apply to module mappings

   - Fix a hard to hit race between module loader error/clean up
     handling and ftrace registration

   - Some code cleanups, notably panic.c and modules code use a unified
     taint_flags table now. This is much cleaner than duplicating the
     taint flag code in modules.c"

* tag 'modules-for-v4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux:
  module: fix DEBUG_SET_MODULE_RONX typo
  module: extend 'rodata=off' boot cmdline parameter to module mappings
  module: Fix a comment above strong_try_module_get()
  module: When modifying a module's text ignore modules which are going away too
  module: Ensure a module's state is set accordingly during module coming cleanup code
  module: remove trailing whitespace
  taint/module: Clean up global and module taint flags handling
  modpost: free allocated memory

1  2 
include/linux/kernel.h
init/main.c
kernel/module.c

diff --combined include/linux/kernel.h
index d234cd31e75a96fc9a396ecd99c3653bd1a59898,441def77246dc4abd4f9fafc137afb29d10d1ed3..56aec84237ad5b7b55c3a43eb04a882f9eb24d5e
  
  #define REPEAT_BYTE(x)        ((~0ul / 0xff) * (x))
  
 +/* @a is a power of 2 value */
  #define ALIGN(x, a)           __ALIGN_KERNEL((x), (a))
  #define __ALIGN_MASK(x, mask) __ALIGN_KERNEL_MASK((x), (mask))
  #define PTR_ALIGN(p, a)               ((typeof(p))ALIGN((unsigned long)(p), (a)))
  #define IS_ALIGNED(x, a)              (((x) & ((typeof(x))(a) - 1)) == 0)
  
 +/* generic data direction definitions */
 +#define READ                  0
 +#define WRITE                 1
 +
  #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
  
  #define u64_to_user_ptr(x) (          \
@@@ -511,6 -506,15 +511,15 @@@ extern enum system_states 
  #define TAINT_UNSIGNED_MODULE         13
  #define TAINT_SOFTLOCKUP              14
  #define TAINT_LIVEPATCH                       15
+ #define TAINT_FLAGS_COUNT             16
+ struct taint_flag {
+       char true;      /* character printed when tainted */
+       char false;     /* character printed when not tainted */
+       bool module;    /* also show as a per-module taint flag */
+ };
+ extern const struct taint_flag taint_flags[TAINT_FLAGS_COUNT];
  
  extern const char hex_asc[];
  #define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
diff --combined init/main.c
index 23c275cca73a7b9052edc080483a79f49a23db9e,035bd5e997df2ec45e746dd3d5b311dd76c67516..c81c9fa21bc770896c737fd408ef372e37d79c1f
@@@ -81,6 -81,7 +81,7 @@@
  #include <linux/integrity.h>
  #include <linux/proc_ns.h>
  #include <linux/io.h>
+ #include <linux/cache.h>
  
  #include <asm/io.h>
  #include <asm/bugs.h>
@@@ -448,8 -449,6 +449,8 @@@ void __init parse_early_param(void
        done = 1;
  }
  
 +void __init __weak arch_post_acpi_subsys_init(void) { }
 +
  void __init __weak smp_setup_processor_id(void)
  {
  }
@@@ -553,14 -552,6 +554,14 @@@ asmlinkage __visible void __init start_
                 "Interrupts were enabled *very* early, fixing it\n"))
                local_irq_disable();
        idr_init_cache();
 +
 +      /*
 +       * Allow workqueue creation and work item queueing/cancelling
 +       * early.  Work item execution depends on kthreads and starts after
 +       * workqueue_init().
 +       */
 +      workqueue_init_early();
 +
        rcu_init();
  
        /* trace_printk() and trace points may be used after this */
        check_bugs();
  
        acpi_subsystem_init();
 +      arch_post_acpi_subsys_init();
        sfi_init_late();
  
        if (efi_enabled(EFI_RUNTIME_SERVICES)) {
@@@ -925,14 -915,16 +926,16 @@@ static int try_to_run_init_process(cons
  
  static noinline void __init kernel_init_freeable(void);
  
- #ifdef CONFIG_DEBUG_RODATA
static bool rodata_enabled = true;
+ #if defined(CONFIG_DEBUG_RODATA) || defined(CONFIG_DEBUG_SET_MODULE_RONX)
bool rodata_enabled __ro_after_init = true;
  static int __init set_debug_rodata(char *str)
  {
        return strtobool(str, &rodata_enabled);
  }
  __setup("rodata=", set_debug_rodata);
+ #endif
  
+ #ifdef CONFIG_DEBUG_RODATA
  static void mark_readonly(void)
  {
        if (rodata_enabled)
@@@ -991,7 -983,7 +994,7 @@@ static int __ref kernel_init(void *unus
                return 0;
  
        panic("No working init found.  Try passing init= option to kernel. "
 -            "See Linux Documentation/init.txt for guidance.");
 +            "See Linux Documentation/admin-guide/init.rst for guidance.");
  }
  
  static noinline void __init kernel_init_freeable(void)
  
        smp_prepare_cpus(setup_max_cpus);
  
 +      workqueue_init();
 +
        do_pre_smp_initcalls();
        lockup_detector_init();
  
diff --combined kernel/module.c
index 0e54d5bf0097f57954d4848db6a830f5a0bc7072,039ce82803f70ff58d67445096ab45170a38dc64..f7482db0f84316b24940305b006e701fed9cdc4f
@@@ -313,8 -313,11 +313,11 @@@ struct load_info 
        } index;
  };
  
- /* We require a truly strong try_module_get(): 0 means failure due to
-    ongoing or failed initialization etc. */
+ /*
+  * We require a truly strong try_module_get(): 0 means success.
+  * Otherwise an error is returned due to ongoing or failed
+  * initialization etc.
+  */
  static inline int strong_try_module_get(struct module *mod)
  {
        BUG_ON(mod && mod->state == MODULE_STATE_UNFORMED);
@@@ -330,7 -333,7 +333,7 @@@ static inline void add_taint_module(str
                                    enum lockdep_ok lockdep_ok)
  {
        add_taint(flag, lockdep_ok);
-       mod->taints |= (1U << flag);
+       set_bit(flag, &mod->taints);
  }
  
  /*
@@@ -1138,24 -1141,13 +1141,13 @@@ static inline int module_unload_init(st
  static size_t module_flags_taint(struct module *mod, char *buf)
  {
        size_t l = 0;
+       int i;
+       for (i = 0; i < TAINT_FLAGS_COUNT; i++) {
+               if (taint_flags[i].module && test_bit(i, &mod->taints))
+                       buf[l++] = taint_flags[i].true;
+       }
  
-       if (mod->taints & (1 << TAINT_PROPRIETARY_MODULE))
-               buf[l++] = 'P';
-       if (mod->taints & (1 << TAINT_OOT_MODULE))
-               buf[l++] = 'O';
-       if (mod->taints & (1 << TAINT_FORCED_MODULE))
-               buf[l++] = 'F';
-       if (mod->taints & (1 << TAINT_CRAP))
-               buf[l++] = 'C';
-       if (mod->taints & (1 << TAINT_UNSIGNED_MODULE))
-               buf[l++] = 'E';
-       if (mod->taints & (1 << TAINT_LIVEPATCH))
-               buf[l++] = 'K';
-       /*
-        * TAINT_FORCED_RMMOD: could be added.
-        * TAINT_CPU_OUT_OF_SPEC, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
-        * apply to modules.
-        */
        return l;
  }
  
@@@ -1301,9 -1293,8 +1293,9 @@@ static int check_version(Elf_Shdr *sech
                goto bad_version;
        }
  
 -      pr_warn("%s: no symbol version for %s\n", mod->name, symname);
 -      return 0;
 +      /* Broken toolchain. Warn once, then let it go.. */
 +      pr_warn_once("%s: no symbol version for %s\n", mod->name, symname);
 +      return 1;
  
  bad_version:
        pr_warn("%s: disagrees about version of symbol %s\n",
@@@ -1911,6 -1902,9 +1903,9 @@@ static void frob_writable_data(const st
  /* livepatching wants to disable read-only so it can frob module. */
  void module_disable_ro(const struct module *mod)
  {
+       if (!rodata_enabled)
+               return;
        frob_text(&mod->core_layout, set_memory_rw);
        frob_rodata(&mod->core_layout, set_memory_rw);
        frob_ro_after_init(&mod->core_layout, set_memory_rw);
  
  void module_enable_ro(const struct module *mod, bool after_init)
  {
+       if (!rodata_enabled)
+               return;
        frob_text(&mod->core_layout, set_memory_ro);
        frob_rodata(&mod->core_layout, set_memory_ro);
        frob_text(&mod->init_layout, set_memory_ro);
@@@ -1952,6 -1949,9 +1950,9 @@@ void set_all_modules_text_rw(void
  {
        struct module *mod;
  
+       if (!rodata_enabled)
+               return;
        mutex_lock(&module_mutex);
        list_for_each_entry_rcu(mod, &modules, list) {
                if (mod->state == MODULE_STATE_UNFORMED)
@@@ -1968,9 -1968,18 +1969,18 @@@ void set_all_modules_text_ro(void
  {
        struct module *mod;
  
+       if (!rodata_enabled)
+               return;
        mutex_lock(&module_mutex);
        list_for_each_entry_rcu(mod, &modules, list) {
-               if (mod->state == MODULE_STATE_UNFORMED)
+               /*
+                * Ignore going modules since it's possible that ro
+                * protection has already been disabled, otherwise we'll
+                * run into protection faults at module deallocation.
+                */
+               if (mod->state == MODULE_STATE_UNFORMED ||
+                       mod->state == MODULE_STATE_GOING)
                        continue;
  
                frob_text(&mod->core_layout, set_memory_ro);
  
  static void disable_ro_nx(const struct module_layout *layout)
  {
-       frob_text(layout, set_memory_rw);
-       frob_rodata(layout, set_memory_rw);
+       if (rodata_enabled) {
+               frob_text(layout, set_memory_rw);
+               frob_rodata(layout, set_memory_rw);
+               frob_ro_after_init(layout, set_memory_rw);
+       }
        frob_rodata(layout, set_memory_x);
-       frob_ro_after_init(layout, set_memory_rw);
        frob_ro_after_init(layout, set_memory_x);
        frob_writable_data(layout, set_memory_x);
  }
@@@ -3709,6 -3720,7 +3721,7 @@@ static int load_module(struct load_inf
   sysfs_cleanup:
        mod_sysfs_teardown(mod);
   coming_cleanup:
+       mod->state = MODULE_STATE_GOING;
        blocking_notifier_call_chain(&module_notify_list,
                                     MODULE_STATE_GOING, mod);
        klp_module_going(mod);
@@@ -4042,6 -4054,10 +4055,10 @@@ int module_kallsyms_on_each_symbol(int 
  }
  #endif /* CONFIG_KALLSYMS */
  
+ /* Maximum number of characters written by module_flags() */
+ #define MODULE_FLAGS_BUF_SIZE (TAINT_FLAGS_COUNT + 4)
+ /* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */
  static char *module_flags(struct module *mod, char *buf)
  {
        int bx = 0;
@@@ -4086,7 -4102,7 +4103,7 @@@ static void m_stop(struct seq_file *m, 
  static int m_show(struct seq_file *m, void *p)
  {
        struct module *mod = list_entry(p, struct module, list);
-       char buf[8];
+       char buf[MODULE_FLAGS_BUF_SIZE];
  
        /* We always ignore unformed modules. */
        if (mod->state == MODULE_STATE_UNFORMED)
@@@ -4257,7 -4273,7 +4274,7 @@@ EXPORT_SYMBOL_GPL(__module_text_address
  void print_modules(void)
  {
        struct module *mod;
-       char buf[8];
+       char buf[MODULE_FLAGS_BUF_SIZE];
  
        printk(KERN_DEFAULT "Modules linked in:");
        /* Most callers should already have preempt disabled, but make sure */
This page took 0.087316 seconds and 4 git commands to generate.