Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 11 Jun 2014 23:09:14 +0000 (16:09 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 11 Jun 2014 23:09:14 +0000 (16:09 -0700)
Pull module updates from Rusty Russell:
 "Most of this is cleaning up various driver sysfs permissions so we can
  re-add the perm check (we unified the module param and sysfs checks,
  but the module ones were stronger so we weakened them temporarily).

  Param parsing gets documented, and also "--" now forces args to be
  handed to init (and ignored by the kernel).

  Module NX/RO protections get tightened: we now set them before calling
  parse_args()"

* tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
  module: set nx before marking module MODULE_STATE_COMING.
  samples/kobject/: avoid world-writable sysfs files.
  drivers/hid/hid-picolcd_fb: avoid world-writable sysfs files.
  drivers/staging/speakup/: avoid world-writable sysfs files.
  drivers/regulator/virtual: avoid world-writable sysfs files.
  drivers/scsi/pm8001/pm8001_ctl.c: avoid world-writable sysfs files.
  drivers/hid/hid-lg4ff.c: avoid world-writable sysfs files.
  drivers/video/fbdev/sm501fb.c: avoid world-writable sysfs files.
  drivers/mtd/devices/docg3.c: avoid world-writable sysfs files.
  speakup: fix incorrect perms on speakup_acntsa.c
  cpumask.h: silence warning with -Wsign-compare
  Documentation: Update kernel-parameters.tx
  param: hand arguments after -- straight to init
  modpost: Fix resource leak in read_dump()

1  2 
Documentation/kernel-parameters.txt
drivers/scsi/pm8001/pm8001_ctl.c
init/main.c
kernel/module.c
scripts/mod/modpost.c

index b9f67781c577d04118de98dee652baa32568618b,a42b9dd6b46be49bdb957bb6a7a8ac86cc2dd181..6eaa9cdb7094b5785aecc54e55d4cb5bd08a8de9
@@@ -1,27 -1,37 +1,37 @@@
                            Kernel Parameters
                            ~~~~~~~~~~~~~~~~~
  
- The following is a consolidated list of the kernel parameters as implemented
- (mostly) by the __setup() macro and sorted into English Dictionary order
- (defined as ignoring all punctuation and sorting digits before letters in a
- case insensitive manner), and with descriptions where known.
- Module parameters for loadable modules are specified only as the
- parameter name with optional '=' and value as appropriate, such as:
-       modprobe usbcore blinkenlights=1
- Module parameters for modules that are built into the kernel image
- are specified on the kernel command line with the module name plus
- '.' plus parameter name, with '=' and value if appropriate, such as:
-       usbcore.blinkenlights=1
+ The following is a consolidated list of the kernel parameters as
+ implemented by the __setup(), core_param() and module_param() macros
+ and sorted into English Dictionary order (defined as ignoring all
+ punctuation and sorting digits before letters in a case insensitive
+ manner), and with descriptions where known.
+ The kernel parses parameters from the kernel command line up to "--";
+ if it doesn't recognize a parameter and it doesn't contain a '.', the
+ parameter gets passed to init: parameters with '=' go into init's
+ environment, others are passed as command line arguments to init.
+ Everything after "--" is passed as an argument to init.
+ Module parameters can be specified in two ways: via the kernel command
+ line with a module name prefix, or via modprobe, e.g.:
+       (kernel command line) usbcore.blinkenlights=1
+       (modprobe command line) modprobe usbcore blinkenlights=1
+ Parameters for modules which are built into the kernel need to be
+ specified on the kernel command line.  modprobe looks through the
+ kernel command line (/proc/cmdline) and collects module parameters
+ when it loads a module, so the kernel command line can be used for
+ loadable modules too.
  
  Hyphens (dashes) and underscores are equivalent in parameter names, so
        log_buf_len=1M print-fatal-signals=1
  can also be entered as
        log-buf-len=1M print_fatal_signals=1
  
+ Double-quotes can be used to protect spaces in values, e.g.:
+       param="spaces in here"
  
  This document may not be entirely up to date and comprehensive. The command
  "modinfo -p ${modulename}" shows a current list of all parameters of a loadable
@@@ -214,11 -224,6 +224,11 @@@ bytes respectively. Such letter suffixe
                        unusable.  The "log_buf_len" parameter may be useful
                        if you need to capture more output.
  
 +      acpi_force_table_verification   [HW,ACPI]
 +                      Enable table checksum verification during early stage.
 +                      By default, this is disabled due to x86 early mapping
 +                      size limitation.
 +
        acpi_irq_balance [HW,ACPI]
                        ACPI will balance active IRQs
                        default in APIC mode
                        This feature is enabled by default.
                        This option allows to turn off the feature.
  
 -      acpi_no_auto_ssdt       [HW,ACPI] Disable automatic loading of SSDT
 +      acpi_no_static_ssdt     [HW,ACPI]
 +                      Disable installation of static SSDTs at early boot time
 +                      By default, SSDTs contained in the RSDT/XSDT will be
 +                      installed automatically and they will appear under
 +                      /sys/firmware/acpi/tables.
 +                      This option turns off this feature.
 +                      Note that specifying this option does not affect
 +                      dynamic table installation which will install SSDT
 +                      tables to /sys/firmware/acpi/tables/dynamic.
  
        acpica_no_return_repair [HW, ACPI]
                        Disable AML predefined validation mechanism
                        Also note the kernel might malfunction if you disable
                        some critical bits.
  
 -      cma=nn[MG]      [ARM,KNL]
 -                      Sets the size of kernel global memory area for contiguous
 +      cma=nn[MG]@[start[MG][-end[MG]]]
 +                      [ARM,X86,KNL]
 +                      Sets the size of kernel global memory area for
 +                      contiguous memory allocations and optionally the
 +                      placement constraint by the physical address range of
                        memory allocations. For more information, see
                        include/linux/dma-contiguous.h
  
                        which are not unmapped.
  
        earlycon=       [KNL] Output early console device and options.
 +
                uart[8250],io,<addr>[,options]
                uart[8250],mmio,<addr>[,options]
                uart[8250],mmio32,<addr>[,options]
                        (mmio) or 32-bit (mmio32).
                        The options are the same as for ttyS, above.
  
 -      earlyprintk=    [X86,SH,BLACKFIN,ARM]
 +              pl011,<addr>
 +                      Start an early, polled-mode console on a pl011 serial
 +                      port at the specified address. The pl011 serial port
 +                      must already be setup and configured. Options are not
 +                      yet supported.
 +
 +              smh     Use ARM semihosting calls for early console.
 +
 +      earlyprintk=    [X86,SH,BLACKFIN,ARM,M68k]
                        earlyprintk=vga
                        earlyprintk=efi
                        earlyprintk=xen
                        for working out where the kernel is dying during
                        startup.
  
 +      initcall_blacklist=  [KNL] Do not execute a comma-separated list of
 +                      initcall functions.  Useful for debugging built-in
 +                      modules and initcalls.
 +
        initrd=         [BOOT] Specify the location of the initial ramdisk
  
        inport.irq=     [HW] Inport (ATI XL and Microsoft) busmouse driver
        noreplace-smp   [X86-32,SMP] Don't replace SMP instructions
                        with UP alternatives
  
 -      nordrand        [X86] Disable the direct use of the RDRAND
 -                      instruction even if it is supported by the
 -                      processor.  RDRAND is still available to user
 -                      space applications.
 +      nordrand        [X86] Disable kernel use of the RDRAND and
 +                      RDSEED instructions even if they are supported
 +                      by the processor.  RDRAND and RDSEED are still
 +                      available to user space applications.
  
        noresume        [SWSUSP] Disables resume and restores original swap
                        space.
                        timeout < 0: reboot immediately
                        Format: <timeout>
  
 +      crash_kexec_post_notifiers
 +                      Run kdump after running panic-notifiers and dumping
 +                      kmsg. This only for the users who doubt kdump always
 +                      succeeds in any situation.
 +                      Note that this also increases risks of kdump failure,
 +                      because some panic notifiers can make the crashed
 +                      kernel more unstable.
 +
        parkbd.port=    [HW] Parallel port number the keyboard adapter is
                        connected to, default is 0.
                        Format: <parport#>
                        [KNL, SMP] Set scheduler's default relax_domain_level.
                        See Documentation/cgroups/cpusets.txt.
  
 +      relative_sleep_states=
 +                      [SUSPEND] Use sleep state labeling where the deepest
 +                      state available other than hibernation is always "mem".
 +                      Format: { "0" | "1" }
 +                      0 -- Traditional sleep state labels.
 +                      1 -- Relative sleep state labels.
 +
        reserve=        [KNL,BUGS] Force the kernel to ignore some iomem area
  
        reservetop=     [X86-32]
                        the allocated input device; If set to 0, video driver
                        will only send out the event without touching backlight
                        brightness level.
 -                      default: 1
 +                      default: 0
  
        virtio_mmio.device=
                        [VMMIO] Memory mapped virtio (platform) device.
index fe5eee4d0a1133645116fb7af6e799e0154bddf7,62c884e79409dcafab58ced771ad0da9cf25bdc2..a368d77b8d4100dbe267da5f9f419e0a2dbaa68f
@@@ -395,8 -395,6 +395,8 @@@ static ssize_t pm8001_ctl_bios_version_
        payload.offset = 0;
        payload.length = 4096;
        payload.func_specific = kzalloc(4096, GFP_KERNEL);
 +      if (!payload.func_specific)
 +              return -ENOMEM;
        PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload);
        wait_for_completion(&completion);
        virt_addr = pm8001_ha->memoryMap.region[NVMD].virt_ptr;
                bios_index++)
                str += sprintf(str, "%c",
                        *((u8 *)((u8 *)virt_addr+bios_index)));
 +      kfree(payload.func_specific);
        return str - buf;
  }
  static DEVICE_ATTR(bios_version, S_IRUGO, pm8001_ctl_bios_version_show, NULL);
@@@ -732,7 -729,7 +732,7 @@@ static ssize_t pm8001_show_update_fw(st
                        flash_error_table[i].reason);
  }
  
- static DEVICE_ATTR(update_fw, S_IRUGO|S_IWUGO,
+ static DEVICE_ATTR(update_fw, S_IRUGO|S_IWUSR|S_IWGRP,
        pm8001_show_update_fw, pm8001_store_update_fw);
  struct device_attribute *pm8001_host_attrs[] = {
        &dev_attr_interface_rev,
diff --combined init/main.c
index 0ec25157deef71160819c326e7c229d431c5de00,e9d458b5d77bd34449473d6b777da545aec8a81b..e8ae1fef0908965b0c5fff7ba7ab8f043e83a980
@@@ -77,7 -77,6 +77,7 @@@
  #include <linux/sched_clock.h>
  #include <linux/context_tracking.h>
  #include <linux/random.h>
 +#include <linux/list.h>
  
  #include <asm/io.h>
  #include <asm/bugs.h>
@@@ -204,13 -203,13 +204,13 @@@ EXPORT_SYMBOL(loops_per_jiffy)
  
  static int __init debug_kernel(char *str)
  {
 -      console_loglevel = 10;
 +      console_loglevel = CONSOLE_LOGLEVEL_DEBUG;
        return 0;
  }
  
  static int __init quiet_kernel(char *str)
  {
 -      console_loglevel = 4;
 +      console_loglevel = CONSOLE_LOGLEVEL_QUIET;
        return 0;
  }
  
@@@ -253,6 -252,27 +253,27 @@@ static int __init repair_env_string(cha
        return 0;
  }
  
+ /* Anything after -- gets handed straight to init. */
+ static int __init set_init_arg(char *param, char *val, const char *unused)
+ {
+       unsigned int i;
+       if (panic_later)
+               return 0;
+       repair_env_string(param, val, unused);
+       for (i = 0; argv_init[i]; i++) {
+               if (i == MAX_INIT_ARGS) {
+                       panic_later = "init";
+                       panic_param = param;
+                       return 0;
+               }
+       }
+       argv_init[i] = param;
+       return 0;
+ }
  /*
   * Unknown boot options get handed to init, unless they look like
   * unused parameters (modprobe will find them in /proc/cmdline).
@@@ -380,7 -400,7 +401,7 @@@ static noinline void __init_refok rest_
         * the init task will end up wanting to create kthreads, which, if
         * we schedule it before we create kthreadd, will OOPS.
         */
 -      kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
 +      kernel_thread(kernel_init, NULL, CLONE_FS);
        numa_default_policy();
        pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
        rcu_read_lock();
@@@ -477,9 -497,9 +498,9 @@@ static void __init mm_init(void
        vmalloc_init();
  }
  
 -asmlinkage void __init start_kernel(void)
 +asmlinkage __visible void __init start_kernel(void)
  {
-       char * command_line;
+       char * command_line, *after_dashes;
        extern const struct kernel_param __start___param[], __stop___param[];
  
        /*
        page_address_init();
        pr_notice("%s", linux_banner);
        setup_arch(&command_line);
 -      mm_init_owner(&init_mm, &init_task);
        mm_init_cpumask(&init_mm);
        setup_command_line(command_line);
        setup_nr_cpu_ids();
  
        pr_notice("Kernel command line: %s\n", boot_command_line);
        parse_early_param();
-       parse_args("Booting kernel", static_command_line, __start___param,
-                  __stop___param - __start___param,
-                  -1, -1, &unknown_bootoption);
+       after_dashes = parse_args("Booting kernel",
+                                 static_command_line, __start___param,
+                                 __stop___param - __start___param,
+                                 -1, -1, &unknown_bootoption);
+       if (after_dashes)
+               parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,
+                          set_init_arg);
  
        jump_label_init();
  
  #ifdef CONFIG_X86
        if (efi_enabled(EFI_RUNTIME_SERVICES))
                efi_enter_virtual_mode();
 +#endif
 +#ifdef CONFIG_X86_ESPFIX64
 +      /* Should be run before the first non-init thread is created */
 +      init_espfix_bsp();
  #endif
        thread_info_cache_init();
        cred_init();
        signals_init();
        /* rootfs populating might need page-writeback */
        page_writeback_init();
 -#ifdef CONFIG_PROC_FS
        proc_root_init();
 -#endif
        cgroup_init();
        cpuset_init();
        taskstats_init_early();
@@@ -668,83 -691,19 +693,83 @@@ static void __init do_ctors(void
  bool initcall_debug;
  core_param(initcall_debug, initcall_debug, bool, 0644);
  
 +#ifdef CONFIG_KALLSYMS
 +struct blacklist_entry {
 +      struct list_head next;
 +      char *buf;
 +};
 +
 +static __initdata_or_module LIST_HEAD(blacklisted_initcalls);
 +
 +static int __init initcall_blacklist(char *str)
 +{
 +      char *str_entry;
 +      struct blacklist_entry *entry;
 +
 +      /* str argument is a comma-separated list of functions */
 +      do {
 +              str_entry = strsep(&str, ",");
 +              if (str_entry) {
 +                      pr_debug("blacklisting initcall %s\n", str_entry);
 +                      entry = alloc_bootmem(sizeof(*entry));
 +                      entry->buf = alloc_bootmem(strlen(str_entry) + 1);
 +                      strcpy(entry->buf, str_entry);
 +                      list_add(&entry->next, &blacklisted_initcalls);
 +              }
 +      } while (str_entry);
 +
 +      return 0;
 +}
 +
 +static bool __init_or_module initcall_blacklisted(initcall_t fn)
 +{
 +      struct list_head *tmp;
 +      struct blacklist_entry *entry;
 +      char *fn_name;
 +
 +      fn_name = kasprintf(GFP_KERNEL, "%pf", fn);
 +      if (!fn_name)
 +              return false;
 +
 +      list_for_each(tmp, &blacklisted_initcalls) {
 +              entry = list_entry(tmp, struct blacklist_entry, next);
 +              if (!strcmp(fn_name, entry->buf)) {
 +                      pr_debug("initcall %s blacklisted\n", fn_name);
 +                      kfree(fn_name);
 +                      return true;
 +              }
 +      }
 +
 +      kfree(fn_name);
 +      return false;
 +}
 +#else
 +static int __init initcall_blacklist(char *str)
 +{
 +      pr_warn("initcall_blacklist requires CONFIG_KALLSYMS\n");
 +      return 0;
 +}
 +
 +static bool __init_or_module initcall_blacklisted(initcall_t fn)
 +{
 +      return false;
 +}
 +#endif
 +__setup("initcall_blacklist=", initcall_blacklist);
 +
  static int __init_or_module do_one_initcall_debug(initcall_t fn)
  {
        ktime_t calltime, delta, rettime;
        unsigned long long duration;
        int ret;
  
 -      pr_debug("calling  %pF @ %i\n", fn, task_pid_nr(current));
 +      printk(KERN_DEBUG "calling  %pF @ %i\n", fn, task_pid_nr(current));
        calltime = ktime_get();
        ret = fn();
        rettime = ktime_get();
        delta = ktime_sub(rettime, calltime);
        duration = (unsigned long long) ktime_to_ns(delta) >> 10;
 -      pr_debug("initcall %pF returned %d after %lld usecs\n",
 +      printk(KERN_DEBUG "initcall %pF returned %d after %lld usecs\n",
                 fn, ret, duration);
  
        return ret;
@@@ -756,9 -715,6 +781,9 @@@ int __init_or_module do_one_initcall(in
        int ret;
        char msgbuf[64];
  
 +      if (initcall_blacklisted(fn))
 +              return -EPERM;
 +
        if (initcall_debug)
                ret = do_one_initcall_debug(fn);
        else
diff --combined kernel/module.c
index 079c4615607d6ed266330a5416529bfcc37e4db0,f944c72d3c8a1ac19391020dc41cbd745d623171..81e727cf6df97d8477edad3e69f97c0f3242dae3
@@@ -815,6 -815,9 +815,6 @@@ SYSCALL_DEFINE2(delete_module, const ch
                return -EFAULT;
        name[MODULE_NAME_LEN-1] = '\0';
  
 -      if (!(flags & O_NONBLOCK))
 -              pr_warn("waiting module removal not supported: please upgrade\n");
 -
        if (mutex_lock_interruptible(&module_mutex) != 0)
                return -EINTR;
  
@@@ -3020,21 -3023,6 +3020,6 @@@ static int do_init_module(struct modul
         */
        current->flags &= ~PF_USED_ASYNC;
  
-       blocking_notifier_call_chain(&module_notify_list,
-                       MODULE_STATE_COMING, mod);
-       /* Set RO and NX regions for core */
-       set_section_ro_nx(mod->module_core,
-                               mod->core_text_size,
-                               mod->core_ro_size,
-                               mod->core_size);
-       /* Set RO and NX regions for init */
-       set_section_ro_nx(mod->module_init,
-                               mod->init_text_size,
-                               mod->init_ro_size,
-                               mod->init_size);
        do_mod_ctors(mod);
        /* Start the module */
        if (mod->init != NULL)
@@@ -3165,9 -3153,26 +3150,26 @@@ static int complete_formation(struct mo
        /* This relies on module_mutex for list integrity. */
        module_bug_finalize(info->hdr, info->sechdrs, mod);
  
+       /* Set RO and NX regions for core */
+       set_section_ro_nx(mod->module_core,
+                               mod->core_text_size,
+                               mod->core_ro_size,
+                               mod->core_size);
+       /* Set RO and NX regions for init */
+       set_section_ro_nx(mod->module_init,
+                               mod->init_text_size,
+                               mod->init_ro_size,
+                               mod->init_size);
        /* Mark state as coming so strong_try_module_get() ignores us,
         * but kallsyms etc. can see us. */
        mod->state = MODULE_STATE_COMING;
+       mutex_unlock(&module_mutex);
+       blocking_notifier_call_chain(&module_notify_list,
+                                    MODULE_STATE_COMING, mod);
+       return 0;
  
  out:
        mutex_unlock(&module_mutex);
@@@ -3190,6 -3195,7 +3192,7 @@@ static int load_module(struct load_inf
  {
        struct module *mod;
        long err;
+       char *after_dashes;
  
        err = module_sig_check(info);
        if (err)
  
        dynamic_debug_setup(info->debug, info->num_debug);
  
 +      /* Ftrace init must be called in the MODULE_STATE_UNFORMED state */
 +      ftrace_module_init(mod);
 +
        /* Finally it's fully formed, ready to start executing. */
        err = complete_formation(mod, info);
        if (err)
                goto ddebug_cleanup;
  
        /* Module is ready to execute: parsing args may do that. */
-       err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
-                        -32768, 32767, unknown_module_param_cb);
-       if (err < 0)
+       after_dashes = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
+                                 -32768, 32767, unknown_module_param_cb);
+       if (IS_ERR(after_dashes)) {
+               err = PTR_ERR(after_dashes);
                goto bug_cleanup;
+       } else if (after_dashes) {
+               pr_warn("%s: parameters '%s' after `--' ignored\n",
+                      mod->name, after_dashes);
+       }
  
        /* Link in to syfs. */
        err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp);
diff --combined scripts/mod/modpost.c
index ea7f9530afa2a3256bbc51e8bc2c4c43039300ca,ea3e2bdf1825dcdc88e2237842e2b5f5ca99decf..026543ba8d8687b6218192d5dd4dd212c442e329
@@@ -316,7 -316,7 +316,7 @@@ static struct symbol *sym_add_exported(
                             s->module->name,
                             is_vmlinux(s->module->name) ?"":".ko");
                } else {
 -                      /* In case Modules.symvers was out of date */
 +                      /* In case Module.symvers was out of date */
                        s->module = mod;
                }
        }
@@@ -2113,8 -2113,10 +2113,10 @@@ static void read_dump(const char *fname
                s->preloaded = 1;
                sym_update_crc(symname, mod, crc, export_no(export));
        }
+       release_file(file, size);
        return;
  fail:
+       release_file(file, size);
        fatal("parse error in symbol dump file\n");
  }