summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
Diffstat (limited to 'init')
-rw-r--r--init/Kconfig54
-rw-r--r--init/do_mounts.c47
-rw-r--r--init/do_mounts_rd.c12
-rw-r--r--init/main.c60
4 files changed, 135 insertions, 38 deletions
diff --git a/init/Kconfig b/init/Kconfig
index 18a98c893d07..296dfcaf613f 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -284,7 +284,7 @@ config AUDIT
config AUDITSYSCALL
bool "Enable system-call auditing support"
- depends on AUDIT && (X86 || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT))
+ depends on AUDIT && (X86 || PARISC || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT))
default y if SECURITY_SELINUX
help
Enable low-overhead system-call auditing infrastructure that
@@ -340,7 +340,8 @@ config VIRT_CPU_ACCOUNTING_NATIVE
config VIRT_CPU_ACCOUNTING_GEN
bool "Full dynticks CPU time accounting"
- depends on HAVE_CONTEXT_TRACKING && 64BIT
+ depends on HAVE_CONTEXT_TRACKING
+ depends on HAVE_VIRT_CPU_ACCOUNTING_GEN
select VIRT_CPU_ACCOUNTING
select CONTEXT_TRACKING
help
@@ -456,6 +457,7 @@ config TREE_RCU
config TREE_PREEMPT_RCU
bool "Preemptible tree-based hierarchical RCU"
depends on PREEMPT
+ select IRQ_WORK
help
This option selects the RCU implementation that is
designed for very large SMP systems with hundreds or
@@ -513,13 +515,29 @@ config RCU_USER_QS
config CONTEXT_TRACKING_FORCE
bool "Force context tracking"
depends on CONTEXT_TRACKING
- default CONTEXT_TRACKING
+ default y if !NO_HZ_FULL
help
- Probe on user/kernel boundaries by default in order to
- test the features that rely on it such as userspace RCU extended
- quiescent states.
- This test is there for debugging until we have a real user like the
- full dynticks mode.
+ The major pre-requirement for full dynticks to work is to
+ support the context tracking subsystem. But there are also
+ other dependencies to provide in order to make the full
+ dynticks working.
+
+ This option stands for testing when an arch implements the
+ context tracking backend but doesn't yet fullfill all the
+ requirements to make the full dynticks feature working.
+ Without the full dynticks, there is no way to test the support
+ for context tracking and the subsystems that rely on it: RCU
+ userspace extended quiescent state and tickless cputime
+ accounting. This option copes with the absence of the full
+ dynticks subsystem by forcing the context tracking on all
+ CPUs in the system.
+
+ Say Y only if you're working on the developpement of an
+ architecture backend for the context tracking.
+
+ Say N otherwise, this option brings an overhead that you
+ don't want in production.
+
config RCU_FANOUT
int "Tree-based hierarchical RCU fanout value"
@@ -813,7 +831,7 @@ config NUMA_BALANCING_DEFAULT_ENABLED
default y
depends on NUMA_BALANCING
help
- If set, autonumic NUMA balancing will be enabled if running on a NUMA
+ If set, automatic NUMA balancing will be enabled if running on a NUMA
machine.
config NUMA_BALANCING
@@ -824,7 +842,7 @@ config NUMA_BALANCING
help
This option adds support for automatic NUMA aware memory/task placement.
The mechanism is quite primitive and is based on migrating memory when
- it is references to the node the task is running on.
+ it has references to the node the task is running on.
This system will be inactive on UMA systems.
@@ -1092,7 +1110,6 @@ config IPC_NS
config USER_NS
bool "User namespace"
- depends on UIDGID_CONVERTED
select UIDGID_STRICT_TYPE_CHECKS
default n
@@ -1126,20 +1143,8 @@ config NET_NS
endif # NAMESPACES
-config UIDGID_CONVERTED
- # True if all of the selected software conmponents are known
- # to have uid_t and gid_t converted to kuid_t and kgid_t
- # where appropriate and are otherwise safe to use with
- # the user namespace.
- bool
- default y
-
- # Filesystems
- depends on XFS_FS = n
-
config UIDGID_STRICT_TYPE_CHECKS
bool "Require conversions between uid/gids and their internal representation"
- depends on UIDGID_CONVERTED
default n
help
While the nececessary conversions are being added to all subsystems this option allows
@@ -1584,7 +1589,7 @@ endchoice
config SLUB_CPU_PARTIAL
default y
- depends on SLUB
+ depends on SLUB && SMP
bool "SLUB per cpu partial cache"
help
Per cpu partial caches accellerate objects allocation and freeing
@@ -1652,6 +1657,7 @@ config BASE_SMALL
menuconfig MODULES
bool "Enable loadable module support"
+ option modules
help
Kernel modules are small pieces of compiled code which can
be inserted in the running kernel, rather than being
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 816014c4627e..8e5addc45874 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -26,6 +26,8 @@
#include <linux/async.h>
#include <linux/fs_struct.h>
#include <linux/slab.h>
+#include <linux/ramfs.h>
+#include <linux/shmem_fs.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_fs_sb.h>
@@ -195,6 +197,8 @@ done:
* is a zero-filled hex representation of the 1-based partition number.
* 7) PARTUUID=<UUID>/PARTNROFF=<int> to select a partition in relation to
* a partition with a known unique id.
+ * 8) <major>:<minor> major and minor number of the device separated by
+ * a colon.
*
* If name doesn't have fall into the categories above, we return (0,0).
* block_class is used to check if something is a disk name. If the disk
@@ -588,3 +592,46 @@ out:
sys_mount(".", "/", NULL, MS_MOVE, NULL);
sys_chroot(".");
}
+
+static bool is_tmpfs;
+static struct dentry *rootfs_mount(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data)
+{
+ static unsigned long once;
+ void *fill = ramfs_fill_super;
+
+ if (test_and_set_bit(0, &once))
+ return ERR_PTR(-ENODEV);
+
+ if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs)
+ fill = shmem_fill_super;
+
+ return mount_nodev(fs_type, flags, data, fill);
+}
+
+static struct file_system_type rootfs_fs_type = {
+ .name = "rootfs",
+ .mount = rootfs_mount,
+ .kill_sb = kill_litter_super,
+};
+
+int __init init_rootfs(void)
+{
+ int err = register_filesystem(&rootfs_fs_type);
+
+ if (err)
+ return err;
+
+ if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] &&
+ (!root_fs_names || strstr(root_fs_names, "tmpfs"))) {
+ err = shmem_init();
+ is_tmpfs = true;
+ } else {
+ err = init_ramfs_fs();
+ }
+
+ if (err)
+ unregister_filesystem(&rootfs_fs_type);
+
+ return err;
+}
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
index 6be2879cca66..7c098ac9068a 100644
--- a/init/do_mounts_rd.c
+++ b/init/do_mounts_rd.c
@@ -57,6 +57,11 @@ static int __init crd_load(int in_fd, int out_fd, decompress_fn deco);
* cramfs
* squashfs
* gzip
+ * bzip2
+ * lzma
+ * xz
+ * lzo
+ * lz4
*/
static int __init
identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor)
@@ -342,6 +347,13 @@ static int __init crd_load(int in_fd, int out_fd, decompress_fn deco)
int result;
crd_infd = in_fd;
crd_outfd = out_fd;
+
+ if (!deco) {
+ pr_emerg("Invalid ramdisk decompression routine. "
+ "Select appropriate config option.\n");
+ panic("Could not decompress initial ramdisk image.");
+ }
+
result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error);
if (decompress_error)
result = 1;
diff --git a/init/main.c b/init/main.c
index d03d2ec2eacf..febc511e078a 100644
--- a/init/main.c
+++ b/init/main.c
@@ -75,6 +75,8 @@
#include <linux/blkdev.h>
#include <linux/elevator.h>
#include <linux/sched_clock.h>
+#include <linux/context_tracking.h>
+#include <linux/random.h>
#include <asm/io.h>
#include <asm/bugs.h>
@@ -122,7 +124,6 @@ EXPORT_SYMBOL(system_state);
extern void time_init(void);
/* Default late time init is NULL. archs can override this later. */
void (*__initdata late_time_init)(void);
-extern void softirq_init(void);
/* Untouched command line saved by arch-specific code. */
char __initdata boot_command_line[COMMAND_LINE_SIZE];
@@ -130,11 +131,20 @@ char __initdata boot_command_line[COMMAND_LINE_SIZE];
char *saved_command_line;
/* Command line for parameter parsing */
static char *static_command_line;
+/* Command line for per-initcall parameter parsing */
+static char *initcall_command_line;
static char *execute_command;
static char *ramdisk_execute_command;
/*
+ * Used to generate warnings if static_key manipulation functions are used
+ * before jump_label_init is called.
+ */
+bool static_key_initialized __read_mostly = false;
+EXPORT_SYMBOL_GPL(static_key_initialized);
+
+/*
* If set, this is an indication to the drivers that reset the underlying
* device before going ahead with the initialization otherwise driver might
* rely on the BIOS and skip the reset operation.
@@ -346,6 +356,7 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { }
static void __init setup_command_line(char *command_line)
{
saved_command_line = alloc_bootmem(strlen (boot_command_line)+1);
+ initcall_command_line = alloc_bootmem(strlen (boot_command_line)+1);
static_command_line = alloc_bootmem(strlen (command_line)+1);
strcpy (saved_command_line, boot_command_line);
strcpy (static_command_line, command_line);
@@ -545,6 +556,7 @@ asmlinkage void __init start_kernel(void)
idr_init_cache();
rcu_init();
tick_nohz_init();
+ context_tracking_init();
radix_tree_init();
/* init some links before init_ISA_irqs() */
early_irq_init();
@@ -690,7 +702,7 @@ int __init_or_module do_one_initcall(initcall_t fn)
if (preempt_count() != count) {
sprintf(msgbuf, "preemption imbalance ");
- preempt_count() = count;
+ preempt_count_set(count);
}
if (irqs_disabled()) {
strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
@@ -742,9 +754,9 @@ static void __init do_initcall_level(int level)
extern const struct kernel_param __start___param[], __stop___param[];
initcall_t *fn;
- strcpy(static_command_line, saved_command_line);
+ strcpy(initcall_command_line, saved_command_line);
parse_args(initcall_level_names[level],
- static_command_line, __start___param,
+ initcall_command_line, __start___param,
__stop___param - __start___param,
level, level,
&repair_env_string);
@@ -778,6 +790,7 @@ static void __init do_basic_setup(void)
do_ctors();
usermodehelper_enable();
do_initcalls();
+ random_int_secret_init();
}
static void __init do_pre_smp_initcalls(void)
@@ -807,10 +820,26 @@ static int run_init_process(const char *init_filename)
(const char __user *const __user *)envp_init);
}
+static int try_to_run_init_process(const char *init_filename)
+{
+ int ret;
+
+ ret = run_init_process(init_filename);
+
+ if (ret && ret != -ENOENT) {
+ pr_err("Starting init: %s exists but couldn't execute it (error %d)\n",
+ init_filename, ret);
+ }
+
+ return ret;
+}
+
static noinline void __init kernel_init_freeable(void);
static int __ref kernel_init(void *unused)
{
+ int ret;
+
kernel_init_freeable();
/* need to finish all async __init code before freeing the memory */
async_synchronize_full();
@@ -822,9 +851,11 @@ static int __ref kernel_init(void *unused)
flush_delayed_fput();
if (ramdisk_execute_command) {
- if (!run_init_process(ramdisk_execute_command))
+ ret = run_init_process(ramdisk_execute_command);
+ if (!ret)
return 0;
- pr_err("Failed to execute %s\n", ramdisk_execute_command);
+ pr_err("Failed to execute %s (error %d)\n",
+ ramdisk_execute_command, ret);
}
/*
@@ -834,18 +865,19 @@ static int __ref kernel_init(void *unused)
* trying to recover a really broken machine.
*/
if (execute_command) {
- if (!run_init_process(execute_command))
+ ret = run_init_process(execute_command);
+ if (!ret)
return 0;
- pr_err("Failed to execute %s. Attempting defaults...\n",
- execute_command);
+ pr_err("Failed to execute %s (error %d). Attempting defaults...\n",
+ execute_command, ret);
}
- if (!run_init_process("/sbin/init") ||
- !run_init_process("/etc/init") ||
- !run_init_process("/bin/init") ||
- !run_init_process("/bin/sh"))
+ if (!try_to_run_init_process("/sbin/init") ||
+ !try_to_run_init_process("/etc/init") ||
+ !try_to_run_init_process("/bin/init") ||
+ !try_to_run_init_process("/bin/sh"))
return 0;
- panic("No init found. Try passing init= option to kernel. "
+ panic("No working init found. Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
}