summaryrefslogtreecommitdiff
path: root/init/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'init/main.c')
-rw-r--r--init/main.c115
1 files changed, 66 insertions, 49 deletions
diff --git a/init/main.c b/init/main.c
index e24b0780fdff..2a1757826397 100644
--- a/init/main.c
+++ b/init/main.c
@@ -88,6 +88,7 @@
#include <linux/sched/task_stack.h>
#include <linux/context_tracking.h>
#include <linux/random.h>
+#include <linux/moduleloader.h>
#include <linux/list.h>
#include <linux/integrity.h>
#include <linux/proc_ns.h>
@@ -99,6 +100,8 @@
#include <linux/init_syscalls.h>
#include <linux/stackdepot.h>
#include <linux/randomize_kstack.h>
+#include <linux/pidfs.h>
+#include <linux/ptdump.h>
#include <net/net_namespace.h>
#include <asm/io.h>
@@ -324,7 +327,7 @@ static int __init xbc_snprint_cmdline(char *buf, size_t size,
{
struct xbc_node *knode, *vnode;
char *end = buf + size;
- const char *val;
+ const char *val, *q;
int ret;
xbc_node_for_each_key_value(root, knode, val) {
@@ -342,8 +345,14 @@ static int __init xbc_snprint_cmdline(char *buf, size_t size,
continue;
}
xbc_array_for_each_value(vnode, val) {
- ret = snprintf(buf, rest(buf, end), "%s=\"%s\" ",
- xbc_namebuf, val);
+ /*
+ * For prettier and more readable /proc/cmdline, only
+ * quote the value when necessary, i.e. when it contains
+ * whitespace.
+ */
+ q = strpbrk(val, " \t\r\n") ? "\"" : "";
+ ret = snprintf(buf, rest(buf, end), "%s=%s%s%s ",
+ xbc_namebuf, q, val, q);
if (ret < 0)
return ret;
buf += ret;
@@ -484,6 +493,11 @@ static int __init warn_bootconfig(char *str)
early_param("bootconfig", warn_bootconfig);
+bool __init cmdline_has_extra_options(void)
+{
+ return extra_command_line || extra_init_args;
+}
+
/* Change NUL term back to "=", to make "param" the whole string. */
static void __init repair_env_string(char *param, char *val)
{
@@ -603,7 +617,6 @@ static int __init rdinit_setup(char *str)
__setup("rdinit=", rdinit_setup);
#ifndef CONFIG_SMP
-static const unsigned int setup_max_cpus = NR_CPUS;
static inline void setup_nr_cpu_ids(void) { }
static inline void smp_prepare_cpus(unsigned int maxcpus) { }
#endif
@@ -620,18 +633,18 @@ static void __init setup_command_line(char *command_line)
if (extra_command_line)
xlen = strlen(extra_command_line);
- if (extra_init_args)
+ if (extra_init_args) {
+ extra_init_args = strim(extra_init_args); /* remove trailing space */
ilen = strlen(extra_init_args) + 4; /* for " -- " */
+ }
- len = xlen + strlen(boot_command_line) + 1;
+ len = xlen + strlen(boot_command_line) + ilen + 1;
- saved_command_line = memblock_alloc(len + ilen, SMP_CACHE_BYTES);
- if (!saved_command_line)
- panic("%s: Failed to allocate %zu bytes\n", __func__, len + ilen);
+ saved_command_line = memblock_alloc_or_panic(len, SMP_CACHE_BYTES);
- static_command_line = memblock_alloc(len, SMP_CACHE_BYTES);
- if (!static_command_line)
- panic("%s: Failed to allocate %zu bytes\n", __func__, len);
+ len = xlen + strlen(command_line) + 1;
+
+ static_command_line = memblock_alloc_or_panic(len, SMP_CACHE_BYTES);
if (xlen) {
/*
@@ -681,7 +694,7 @@ static void __init setup_command_line(char *command_line)
static __initdata DECLARE_COMPLETION(kthreadd_done);
-noinline void __ref __noreturn rest_init(void)
+static noinline void __ref __noreturn rest_init(void)
{
struct task_struct *tsk;
int pid;
@@ -737,10 +750,7 @@ static int __init do_early_param(char *param, char *val,
const struct obs_kernel_param *p;
for (p = __setup_start; p < __setup_end; p++) {
- if ((p->early && parameq(param, p->str)) ||
- (strcmp(param, "console") == 0 &&
- strcmp(p->str, "earlycon") == 0)
- ) {
+ if (p->early && parameq(param, p->str)) {
if (p->setup_func(val) != 0)
pr_warn("Malformed early option '%s'\n", param);
}
@@ -776,6 +786,10 @@ void __init __weak smp_setup_processor_id(void)
{
}
+void __init __weak smp_prepare_boot_cpu(void)
+{
+}
+
# if THREAD_SIZE >= PAGE_SIZE
void __init __weak thread_stack_cache_init(void)
{
@@ -822,11 +836,6 @@ static int __init early_randomize_kstack_offset(char *buf)
early_param("randomize_kstack_offset", early_randomize_kstack_offset);
#endif
-void __init __weak __noreturn arch_call_rest_init(void)
-{
- rest_init();
-}
-
static void __init print_unknown_bootoptions(void)
{
char *unknown_options;
@@ -870,6 +879,19 @@ static void __init print_unknown_bootoptions(void)
memblock_free(unknown_options, len);
}
+static void __init early_numa_node_init(void)
+{
+#ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID
+#ifndef cpu_to_node
+ int cpu;
+
+ /* The early_cpu_to_node() should be ready here. */
+ for_each_possible_cpu(cpu)
+ set_cpu_numa_node(cpu, early_cpu_to_node(cpu));
+#endif
+#endif
+}
+
asmlinkage __visible __init __no_sanitize_address __noreturn __no_stack_protector
void start_kernel(void)
{
@@ -893,18 +915,21 @@ void start_kernel(void)
boot_cpu_init();
page_address_init();
pr_notice("%s", linux_banner);
- early_security_init();
setup_arch(&command_line);
+ /* Static keys and static calls are needed by LSMs */
+ jump_label_init();
+ static_call_init();
+ early_security_init();
setup_boot_config();
setup_command_line(command_line);
setup_nr_cpu_ids();
setup_per_cpu_areas();
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
+ early_numa_node_init();
boot_cpu_hotplug_init();
pr_notice("Kernel command line: %s\n", saved_command_line);
/* parameters may set static keys */
- jump_label_init();
parse_early_param();
after_dashes = parse_args("Booting kernel",
static_command_line, __start___param,
@@ -963,6 +988,7 @@ void start_kernel(void)
workqueue_init_early();
rcu_init();
+ kvfree_rcu_init();
/* Trace events are available after this */
trace_init();
@@ -1059,6 +1085,7 @@ void start_kernel(void)
seq_file_init();
proc_root_init();
nsfs_init();
+ pidfs_init();
cpuset_init();
cgroup_init();
taskstats_init_early();
@@ -1069,7 +1096,7 @@ void start_kernel(void)
kcsan_init();
/* Do the rest non-__init'ed, we're now alive */
- arch_call_rest_init();
+ rest_init();
/*
* Avoid stack canaries in callers of boot_init_stack_canary for gcc-10
@@ -1115,16 +1142,10 @@ static int __init initcall_blacklist(char *str)
str_entry = strsep(&str, ",");
if (str_entry) {
pr_debug("blacklisting initcall %s\n", str_entry);
- entry = memblock_alloc(sizeof(*entry),
+ entry = memblock_alloc_or_panic(sizeof(*entry),
SMP_CACHE_BYTES);
- if (!entry)
- panic("%s: Failed to allocate %zu bytes\n",
- __func__, sizeof(*entry));
- entry->buf = memblock_alloc(strlen(str_entry) + 1,
+ entry->buf = memblock_alloc_or_panic(strlen(str_entry) + 1,
SMP_CACHE_BYTES);
- if (!entry->buf)
- panic("%s: Failed to allocate %zu bytes\n",
- __func__, strlen(str_entry) + 1);
strcpy(entry->buf, str_entry);
list_add(&entry->next, &blacklisted_initcalls);
}
@@ -1396,33 +1417,28 @@ static int __init set_debug_rodata(char *str)
early_param("rodata", set_debug_rodata);
#endif
-#ifdef CONFIG_STRICT_KERNEL_RWX
static void mark_readonly(void)
{
- if (rodata_enabled) {
+ if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX) && rodata_enabled) {
/*
* load_module() results in W+X mappings, which are cleaned
- * up with call_rcu(). Let's make sure that queued work is
+ * up with init_free_wq. Let's make sure that queued work is
* flushed so that we don't hit false positives looking for
* insecure pages which are W+X.
*/
- rcu_barrier();
+ flush_module_init_free_work();
+ jump_label_init_ro();
mark_rodata_ro();
+ debug_checkwx();
rodata_test();
- } else
+ } else if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) {
pr_info("Kernel memory protection disabled.\n");
+ } else if (IS_ENABLED(CONFIG_ARCH_HAS_STRICT_KERNEL_RWX)) {
+ pr_warn("Kernel memory protection not selected by kernel config.\n");
+ } else {
+ pr_warn("This architecture does not have kernel memory protection.\n");
+ }
}
-#elif defined(CONFIG_ARCH_HAS_STRICT_KERNEL_RWX)
-static inline void mark_readonly(void)
-{
- pr_warn("Kernel memory protection not selected by kernel config.\n");
-}
-#else
-static inline void mark_readonly(void)
-{
- pr_warn("This architecture does not have kernel memory protection.\n");
-}
-#endif
void __weak free_initmem(void)
{
@@ -1545,6 +1561,7 @@ static noinline void __init kernel_init_freeable(void)
sched_init_smp();
workqueue_init_topology();
+ async_init();
padata_init();
page_alloc_init_late();