.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * linux/init/main.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
25 | 26 | #include <linux/ioport.h> |
---|
26 | 27 | #include <linux/init.h> |
---|
27 | 28 | #include <linux/initrd.h> |
---|
28 | | -#include <linux/bootmem.h> |
---|
| 29 | +#include <linux/memblock.h> |
---|
29 | 30 | #include <linux/acpi.h> |
---|
| 31 | +#include <linux/bootconfig.h> |
---|
30 | 32 | #include <linux/console.h> |
---|
31 | 33 | #include <linux/nmi.h> |
---|
32 | 34 | #include <linux/percpu.h> |
---|
33 | 35 | #include <linux/kmod.h> |
---|
| 36 | +#include <linux/kprobes.h> |
---|
34 | 37 | #include <linux/vmalloc.h> |
---|
35 | 38 | #include <linux/kernel_stat.h> |
---|
36 | 39 | #include <linux/start_kernel.h> |
---|
37 | 40 | #include <linux/security.h> |
---|
38 | 41 | #include <linux/smp.h> |
---|
39 | 42 | #include <linux/profile.h> |
---|
| 43 | +#include <linux/kfence.h> |
---|
40 | 44 | #include <linux/rcupdate.h> |
---|
41 | 45 | #include <linux/moduleparam.h> |
---|
42 | 46 | #include <linux/kallsyms.h> |
---|
.. | .. |
---|
61 | 65 | #include <linux/debugobjects.h> |
---|
62 | 66 | #include <linux/lockdep.h> |
---|
63 | 67 | #include <linux/kmemleak.h> |
---|
| 68 | +#include <linux/padata.h> |
---|
64 | 69 | #include <linux/pid_namespace.h> |
---|
65 | | -#include <linux/device.h> |
---|
| 70 | +#include <linux/device/driver.h> |
---|
66 | 71 | #include <linux/kthread.h> |
---|
67 | 72 | #include <linux/sched.h> |
---|
68 | 73 | #include <linux/sched/init.h> |
---|
.. | .. |
---|
91 | 96 | #include <linux/cache.h> |
---|
92 | 97 | #include <linux/rodata_test.h> |
---|
93 | 98 | #include <linux/jump_label.h> |
---|
94 | | -#include <linux/mem_encrypt.h> |
---|
| 99 | +#include <linux/kcsan.h> |
---|
| 100 | +#include <linux/init_syscalls.h> |
---|
| 101 | +#include <linux/stackdepot.h> |
---|
95 | 102 | |
---|
96 | 103 | #include <asm/io.h> |
---|
97 | | -#include <asm/bugs.h> |
---|
98 | 104 | #include <asm/setup.h> |
---|
99 | 105 | #include <asm/sections.h> |
---|
100 | 106 | #include <asm/cacheflush.h> |
---|
101 | 107 | |
---|
102 | 108 | #define CREATE_TRACE_POINTS |
---|
103 | 109 | #include <trace/events/initcall.h> |
---|
| 110 | + |
---|
| 111 | +#include <kunit/test.h> |
---|
104 | 112 | |
---|
105 | 113 | static int kernel_init(void *); |
---|
106 | 114 | |
---|
.. | .. |
---|
133 | 141 | char __initdata boot_command_line[COMMAND_LINE_SIZE]; |
---|
134 | 142 | /* Untouched saved command line (eg. for /proc) */ |
---|
135 | 143 | char *saved_command_line; |
---|
136 | | -EXPORT_SYMBOL_GPL(saved_command_line); |
---|
137 | 144 | /* Command line for parameter parsing */ |
---|
138 | 145 | static char *static_command_line; |
---|
139 | | -/* Command line for per-initcall parameter parsing */ |
---|
140 | | -static char *initcall_command_line; |
---|
| 146 | +/* Untouched extra command line */ |
---|
| 147 | +static char *extra_command_line; |
---|
| 148 | +/* Extra init arguments */ |
---|
| 149 | +static char *extra_init_args; |
---|
| 150 | + |
---|
| 151 | +#ifdef CONFIG_BOOT_CONFIG |
---|
| 152 | +/* Is bootconfig on command line? */ |
---|
| 153 | +static bool bootconfig_found; |
---|
| 154 | +static bool initargs_found; |
---|
| 155 | +#else |
---|
| 156 | +# define bootconfig_found false |
---|
| 157 | +# define initargs_found false |
---|
| 158 | +#endif |
---|
141 | 159 | |
---|
142 | 160 | static char *execute_command; |
---|
143 | | -static char *ramdisk_execute_command; |
---|
| 161 | +static char *ramdisk_execute_command = "/init"; |
---|
144 | 162 | |
---|
145 | 163 | /* |
---|
146 | 164 | * Used to generate warnings if static_key manipulation functions are used |
---|
.. | .. |
---|
245 | 263 | |
---|
246 | 264 | early_param("loglevel", loglevel); |
---|
247 | 265 | |
---|
248 | | -/* Change NUL term back to "=", to make "param" the whole string. */ |
---|
249 | | -static int __init repair_env_string(char *param, char *val, |
---|
| 266 | +#ifdef CONFIG_BLK_DEV_INITRD |
---|
| 267 | +static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum) |
---|
| 268 | +{ |
---|
| 269 | + u32 size, csum; |
---|
| 270 | + char *data; |
---|
| 271 | + u32 *hdr; |
---|
| 272 | + int i; |
---|
| 273 | + |
---|
| 274 | + if (!initrd_end) |
---|
| 275 | + return NULL; |
---|
| 276 | + |
---|
| 277 | + data = (char *)initrd_end - BOOTCONFIG_MAGIC_LEN; |
---|
| 278 | + /* |
---|
| 279 | + * Since Grub may align the size of initrd to 4, we must |
---|
| 280 | + * check the preceding 3 bytes as well. |
---|
| 281 | + */ |
---|
| 282 | + for (i = 0; i < 4; i++) { |
---|
| 283 | + if (!memcmp(data, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN)) |
---|
| 284 | + goto found; |
---|
| 285 | + data--; |
---|
| 286 | + } |
---|
| 287 | + return NULL; |
---|
| 288 | + |
---|
| 289 | +found: |
---|
| 290 | + hdr = (u32 *)(data - 8); |
---|
| 291 | + size = le32_to_cpu(hdr[0]); |
---|
| 292 | + csum = le32_to_cpu(hdr[1]); |
---|
| 293 | + |
---|
| 294 | + data = ((void *)hdr) - size; |
---|
| 295 | + if ((unsigned long)data < initrd_start) { |
---|
| 296 | + pr_err("bootconfig size %d is greater than initrd size %ld\n", |
---|
| 297 | + size, initrd_end - initrd_start); |
---|
| 298 | + return NULL; |
---|
| 299 | + } |
---|
| 300 | + |
---|
| 301 | + /* Remove bootconfig from initramfs/initrd */ |
---|
| 302 | + initrd_end = (unsigned long)data; |
---|
| 303 | + if (_size) |
---|
| 304 | + *_size = size; |
---|
| 305 | + if (_csum) |
---|
| 306 | + *_csum = csum; |
---|
| 307 | + |
---|
| 308 | + return data; |
---|
| 309 | +} |
---|
| 310 | +#else |
---|
| 311 | +static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum) |
---|
| 312 | +{ |
---|
| 313 | + return NULL; |
---|
| 314 | +} |
---|
| 315 | +#endif |
---|
| 316 | + |
---|
| 317 | +#ifdef CONFIG_BOOT_CONFIG |
---|
| 318 | + |
---|
| 319 | +static char xbc_namebuf[XBC_KEYLEN_MAX] __initdata; |
---|
| 320 | + |
---|
| 321 | +#define rest(dst, end) ((end) > (dst) ? (end) - (dst) : 0) |
---|
| 322 | + |
---|
| 323 | +static int __init xbc_snprint_cmdline(char *buf, size_t size, |
---|
| 324 | + struct xbc_node *root) |
---|
| 325 | +{ |
---|
| 326 | + struct xbc_node *knode, *vnode; |
---|
| 327 | + char *end = buf + size; |
---|
| 328 | + const char *val; |
---|
| 329 | + int ret; |
---|
| 330 | + |
---|
| 331 | + xbc_node_for_each_key_value(root, knode, val) { |
---|
| 332 | + ret = xbc_node_compose_key_after(root, knode, |
---|
| 333 | + xbc_namebuf, XBC_KEYLEN_MAX); |
---|
| 334 | + if (ret < 0) |
---|
| 335 | + return ret; |
---|
| 336 | + |
---|
| 337 | + vnode = xbc_node_get_child(knode); |
---|
| 338 | + if (!vnode) { |
---|
| 339 | + ret = snprintf(buf, rest(buf, end), "%s ", xbc_namebuf); |
---|
| 340 | + if (ret < 0) |
---|
| 341 | + return ret; |
---|
| 342 | + buf += ret; |
---|
| 343 | + continue; |
---|
| 344 | + } |
---|
| 345 | + xbc_array_for_each_value(vnode, val) { |
---|
| 346 | + ret = snprintf(buf, rest(buf, end), "%s=\"%s\" ", |
---|
| 347 | + xbc_namebuf, val); |
---|
| 348 | + if (ret < 0) |
---|
| 349 | + return ret; |
---|
| 350 | + buf += ret; |
---|
| 351 | + } |
---|
| 352 | + } |
---|
| 353 | + |
---|
| 354 | + return buf - (end - size); |
---|
| 355 | +} |
---|
| 356 | +#undef rest |
---|
| 357 | + |
---|
| 358 | +/* Make an extra command line under given key word */ |
---|
| 359 | +static char * __init xbc_make_cmdline(const char *key) |
---|
| 360 | +{ |
---|
| 361 | + struct xbc_node *root; |
---|
| 362 | + char *new_cmdline; |
---|
| 363 | + int ret, len = 0; |
---|
| 364 | + |
---|
| 365 | + root = xbc_find_node(key); |
---|
| 366 | + if (!root) |
---|
| 367 | + return NULL; |
---|
| 368 | + |
---|
| 369 | + /* Count required buffer size */ |
---|
| 370 | + len = xbc_snprint_cmdline(NULL, 0, root); |
---|
| 371 | + if (len <= 0) |
---|
| 372 | + return NULL; |
---|
| 373 | + |
---|
| 374 | + new_cmdline = memblock_alloc(len + 1, SMP_CACHE_BYTES); |
---|
| 375 | + if (!new_cmdline) { |
---|
| 376 | + pr_err("Failed to allocate memory for extra kernel cmdline.\n"); |
---|
| 377 | + return NULL; |
---|
| 378 | + } |
---|
| 379 | + |
---|
| 380 | + ret = xbc_snprint_cmdline(new_cmdline, len + 1, root); |
---|
| 381 | + if (ret < 0 || ret > len) { |
---|
| 382 | + pr_err("Failed to print extra kernel cmdline.\n"); |
---|
| 383 | + memblock_free(__pa(new_cmdline), len + 1); |
---|
| 384 | + return NULL; |
---|
| 385 | + } |
---|
| 386 | + |
---|
| 387 | + return new_cmdline; |
---|
| 388 | +} |
---|
| 389 | + |
---|
| 390 | +static int __init bootconfig_params(char *param, char *val, |
---|
250 | 391 | const char *unused, void *arg) |
---|
| 392 | +{ |
---|
| 393 | + if (strcmp(param, "bootconfig") == 0) { |
---|
| 394 | + bootconfig_found = true; |
---|
| 395 | + } |
---|
| 396 | + return 0; |
---|
| 397 | +} |
---|
| 398 | + |
---|
| 399 | +static void __init setup_boot_config(const char *cmdline) |
---|
| 400 | +{ |
---|
| 401 | + static char tmp_cmdline[COMMAND_LINE_SIZE] __initdata; |
---|
| 402 | + const char *msg; |
---|
| 403 | + int pos; |
---|
| 404 | + u32 size, csum; |
---|
| 405 | + char *data, *copy, *err; |
---|
| 406 | + int ret; |
---|
| 407 | + |
---|
| 408 | + /* Cut out the bootconfig data even if we have no bootconfig option */ |
---|
| 409 | + data = get_boot_config_from_initrd(&size, &csum); |
---|
| 410 | + |
---|
| 411 | + strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); |
---|
| 412 | + err = parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL, |
---|
| 413 | + bootconfig_params); |
---|
| 414 | + |
---|
| 415 | + if (IS_ERR(err) || !bootconfig_found) |
---|
| 416 | + return; |
---|
| 417 | + |
---|
| 418 | + /* parse_args() stops at '--' and returns an address */ |
---|
| 419 | + if (err) |
---|
| 420 | + initargs_found = true; |
---|
| 421 | + |
---|
| 422 | + if (!data) { |
---|
| 423 | + pr_err("'bootconfig' found on command line, but no bootconfig found\n"); |
---|
| 424 | + return; |
---|
| 425 | + } |
---|
| 426 | + |
---|
| 427 | + if (size >= XBC_DATA_MAX) { |
---|
| 428 | + pr_err("bootconfig size %d greater than max size %d\n", |
---|
| 429 | + size, XBC_DATA_MAX); |
---|
| 430 | + return; |
---|
| 431 | + } |
---|
| 432 | + |
---|
| 433 | + if (xbc_calc_checksum(data, size) != csum) { |
---|
| 434 | + pr_err("bootconfig checksum failed\n"); |
---|
| 435 | + return; |
---|
| 436 | + } |
---|
| 437 | + |
---|
| 438 | + copy = memblock_alloc(size + 1, SMP_CACHE_BYTES); |
---|
| 439 | + if (!copy) { |
---|
| 440 | + pr_err("Failed to allocate memory for bootconfig\n"); |
---|
| 441 | + return; |
---|
| 442 | + } |
---|
| 443 | + |
---|
| 444 | + memcpy(copy, data, size); |
---|
| 445 | + copy[size] = '\0'; |
---|
| 446 | + |
---|
| 447 | + ret = xbc_init(copy, &msg, &pos); |
---|
| 448 | + if (ret < 0) { |
---|
| 449 | + if (pos < 0) |
---|
| 450 | + pr_err("Failed to init bootconfig: %s.\n", msg); |
---|
| 451 | + else |
---|
| 452 | + pr_err("Failed to parse bootconfig: %s at %d.\n", |
---|
| 453 | + msg, pos); |
---|
| 454 | + } else { |
---|
| 455 | + pr_info("Load bootconfig: %d bytes %d nodes\n", size, ret); |
---|
| 456 | + /* keys starting with "kernel." are passed via cmdline */ |
---|
| 457 | + extra_command_line = xbc_make_cmdline("kernel"); |
---|
| 458 | + /* Also, "init." keys are init arguments */ |
---|
| 459 | + extra_init_args = xbc_make_cmdline("init"); |
---|
| 460 | + } |
---|
| 461 | + return; |
---|
| 462 | +} |
---|
| 463 | + |
---|
| 464 | +#else |
---|
| 465 | + |
---|
| 466 | +static void __init setup_boot_config(const char *cmdline) |
---|
| 467 | +{ |
---|
| 468 | + /* Remove bootconfig data from initrd */ |
---|
| 469 | + get_boot_config_from_initrd(NULL, NULL); |
---|
| 470 | +} |
---|
| 471 | + |
---|
| 472 | +static int __init warn_bootconfig(char *str) |
---|
| 473 | +{ |
---|
| 474 | + pr_warn("WARNING: 'bootconfig' found on the kernel command line but CONFIG_BOOT_CONFIG is not set.\n"); |
---|
| 475 | + return 0; |
---|
| 476 | +} |
---|
| 477 | +early_param("bootconfig", warn_bootconfig); |
---|
| 478 | + |
---|
| 479 | +#endif |
---|
| 480 | + |
---|
| 481 | +/* Change NUL term back to "=", to make "param" the whole string. */ |
---|
| 482 | +static void __init repair_env_string(char *param, char *val) |
---|
251 | 483 | { |
---|
252 | 484 | if (val) { |
---|
253 | 485 | /* param=val or param="val"? */ |
---|
.. | .. |
---|
256 | 488 | else if (val == param+strlen(param)+2) { |
---|
257 | 489 | val[-2] = '='; |
---|
258 | 490 | memmove(val-1, val, strlen(val)+1); |
---|
259 | | - val--; |
---|
260 | 491 | } else |
---|
261 | 492 | BUG(); |
---|
262 | 493 | } |
---|
263 | | - return 0; |
---|
264 | 494 | } |
---|
265 | 495 | |
---|
266 | 496 | /* Anything after -- gets handed straight to init. */ |
---|
.. | .. |
---|
272 | 502 | if (panic_later) |
---|
273 | 503 | return 0; |
---|
274 | 504 | |
---|
275 | | - repair_env_string(param, val, unused, NULL); |
---|
| 505 | + repair_env_string(param, val); |
---|
276 | 506 | |
---|
277 | 507 | for (i = 0; argv_init[i]; i++) { |
---|
278 | 508 | if (i == MAX_INIT_ARGS) { |
---|
.. | .. |
---|
292 | 522 | static int __init unknown_bootoption(char *param, char *val, |
---|
293 | 523 | const char *unused, void *arg) |
---|
294 | 524 | { |
---|
295 | | - repair_env_string(param, val, unused, NULL); |
---|
| 525 | + size_t len = strlen(param); |
---|
| 526 | + |
---|
| 527 | + repair_env_string(param, val); |
---|
296 | 528 | |
---|
297 | 529 | /* Handle obsolete-style parameters */ |
---|
298 | 530 | if (obsolete_checksetup(param)) |
---|
299 | 531 | return 0; |
---|
300 | 532 | |
---|
301 | 533 | /* Unused module parameter. */ |
---|
302 | | - if (strchr(param, '.') && (!val || strchr(param, '.') < val)) |
---|
| 534 | + if (strnchr(param, len, '.')) |
---|
303 | 535 | return 0; |
---|
304 | 536 | |
---|
305 | 537 | if (panic_later) |
---|
.. | .. |
---|
313 | 545 | panic_later = "env"; |
---|
314 | 546 | panic_param = param; |
---|
315 | 547 | } |
---|
316 | | - if (!strncmp(param, envp_init[i], val - param)) |
---|
| 548 | + if (!strncmp(param, envp_init[i], len+1)) |
---|
317 | 549 | break; |
---|
318 | 550 | } |
---|
319 | 551 | envp_init[i] = param; |
---|
.. | .. |
---|
374 | 606 | */ |
---|
375 | 607 | static void __init setup_command_line(char *command_line) |
---|
376 | 608 | { |
---|
377 | | - saved_command_line = |
---|
378 | | - memblock_virt_alloc(strlen(boot_command_line) + 1, 0); |
---|
379 | | - initcall_command_line = |
---|
380 | | - memblock_virt_alloc(strlen(boot_command_line) + 1, 0); |
---|
381 | | - static_command_line = memblock_virt_alloc(strlen(command_line) + 1, 0); |
---|
382 | | - strcpy(saved_command_line, boot_command_line); |
---|
383 | | - strcpy(static_command_line, command_line); |
---|
| 609 | + size_t len, xlen = 0, ilen = 0; |
---|
| 610 | + |
---|
| 611 | + if (extra_command_line) |
---|
| 612 | + xlen = strlen(extra_command_line); |
---|
| 613 | + if (extra_init_args) |
---|
| 614 | + ilen = strlen(extra_init_args) + 4; /* for " -- " */ |
---|
| 615 | + |
---|
| 616 | + len = xlen + strlen(boot_command_line) + 1; |
---|
| 617 | + |
---|
| 618 | + saved_command_line = memblock_alloc(len + ilen, SMP_CACHE_BYTES); |
---|
| 619 | + if (!saved_command_line) |
---|
| 620 | + panic("%s: Failed to allocate %zu bytes\n", __func__, len + ilen); |
---|
| 621 | + |
---|
| 622 | + static_command_line = memblock_alloc(len, SMP_CACHE_BYTES); |
---|
| 623 | + if (!static_command_line) |
---|
| 624 | + panic("%s: Failed to allocate %zu bytes\n", __func__, len); |
---|
| 625 | + |
---|
| 626 | + if (xlen) { |
---|
| 627 | + /* |
---|
| 628 | + * We have to put extra_command_line before boot command |
---|
| 629 | + * lines because there could be dashes (separator of init |
---|
| 630 | + * command line) in the command lines. |
---|
| 631 | + */ |
---|
| 632 | + strcpy(saved_command_line, extra_command_line); |
---|
| 633 | + strcpy(static_command_line, extra_command_line); |
---|
| 634 | + } |
---|
| 635 | + strcpy(saved_command_line + xlen, boot_command_line); |
---|
| 636 | + strcpy(static_command_line + xlen, command_line); |
---|
| 637 | + |
---|
| 638 | + if (ilen) { |
---|
| 639 | + /* |
---|
| 640 | + * Append supplemental init boot args to saved_command_line |
---|
| 641 | + * so that user can check what command line options passed |
---|
| 642 | + * to init. |
---|
| 643 | + */ |
---|
| 644 | + len = strlen(saved_command_line); |
---|
| 645 | + if (initargs_found) { |
---|
| 646 | + saved_command_line[len++] = ' '; |
---|
| 647 | + } else { |
---|
| 648 | + strcpy(saved_command_line + len, " -- "); |
---|
| 649 | + len += 4; |
---|
| 650 | + } |
---|
| 651 | + |
---|
| 652 | + strcpy(saved_command_line + len, extra_init_args); |
---|
| 653 | + } |
---|
384 | 654 | } |
---|
385 | 655 | |
---|
386 | 656 | /* |
---|
.. | .. |
---|
394 | 664 | |
---|
395 | 665 | static __initdata DECLARE_COMPLETION(kthreadd_done); |
---|
396 | 666 | |
---|
397 | | -static noinline void __ref rest_init(void) |
---|
| 667 | +noinline void __ref rest_init(void) |
---|
398 | 668 | { |
---|
399 | 669 | struct task_struct *tsk; |
---|
400 | 670 | int pid; |
---|
.. | .. |
---|
424 | 694 | |
---|
425 | 695 | /* |
---|
426 | 696 | * Enable might_sleep() and smp_processor_id() checks. |
---|
427 | | - * They cannot be enabled earlier because with CONFIG_PREEMPT=y |
---|
| 697 | + * They cannot be enabled earlier because with CONFIG_PREEMPTION=y |
---|
428 | 698 | * kernel_thread() would trigger might_sleep() splats. With |
---|
429 | 699 | * CONFIG_PREEMPT_VOLUNTARY=y the init task might have scheduled |
---|
430 | 700 | * already, but it's stuck on the kthreadd_done completion. |
---|
.. | .. |
---|
494 | 764 | } |
---|
495 | 765 | #endif |
---|
496 | 766 | |
---|
497 | | -void __init __weak mem_encrypt_init(void) { } |
---|
| 767 | +void __init __weak poking_init(void) { } |
---|
| 768 | + |
---|
| 769 | +void __init __weak pgtable_cache_init(void) { } |
---|
498 | 770 | |
---|
499 | 771 | bool initcall_debug; |
---|
500 | 772 | core_param(initcall_debug, initcall_debug, bool, 0644); |
---|
.. | .. |
---|
542 | 814 | * bigger than MAX_ORDER unless SPARSEMEM. |
---|
543 | 815 | */ |
---|
544 | 816 | page_ext_init_flatmem(); |
---|
| 817 | + init_mem_debugging_and_hardening(); |
---|
| 818 | + kfence_alloc_pool(); |
---|
545 | 819 | report_meminit(); |
---|
| 820 | + stack_depot_init(); |
---|
546 | 821 | mem_init(); |
---|
| 822 | + /* page_owner must be initialized after buddy is ready */ |
---|
| 823 | + page_ext_init_flatmem_late(); |
---|
547 | 824 | kmem_cache_init(); |
---|
| 825 | + kmemleak_init(); |
---|
548 | 826 | pgtable_init(); |
---|
| 827 | + debug_objects_mem_init(); |
---|
549 | 828 | vmalloc_init(); |
---|
550 | 829 | ioremap_huge_init(); |
---|
551 | 830 | /* Should be run before the first non-init thread is created */ |
---|
552 | 831 | init_espfix_bsp(); |
---|
553 | 832 | /* Should be run after espfix64 is set up. */ |
---|
554 | 833 | pti_init(); |
---|
| 834 | + mm_cache_init(); |
---|
555 | 835 | } |
---|
556 | 836 | |
---|
557 | | -asmlinkage __visible void __init start_kernel(void) |
---|
| 837 | +void __init __weak arch_call_rest_init(void) |
---|
| 838 | +{ |
---|
| 839 | + rest_init(); |
---|
| 840 | +} |
---|
| 841 | + |
---|
| 842 | +asmlinkage __visible void __init __no_sanitize_address start_kernel(void) |
---|
558 | 843 | { |
---|
559 | 844 | char *command_line; |
---|
560 | 845 | char *after_dashes; |
---|
.. | .. |
---|
575 | 860 | boot_cpu_init(); |
---|
576 | 861 | page_address_init(); |
---|
577 | 862 | pr_notice("%s", linux_banner); |
---|
| 863 | + early_security_init(); |
---|
578 | 864 | setup_arch(&command_line); |
---|
579 | | - mm_init_cpumask(&init_mm); |
---|
| 865 | + setup_boot_config(command_line); |
---|
580 | 866 | setup_command_line(command_line); |
---|
581 | 867 | setup_nr_cpu_ids(); |
---|
582 | 868 | setup_per_cpu_areas(); |
---|
583 | | - softirq_early_init(); |
---|
584 | 869 | smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ |
---|
585 | 870 | boot_cpu_hotplug_init(); |
---|
586 | 871 | |
---|
.. | .. |
---|
589 | 874 | |
---|
590 | 875 | #ifdef CONFIG_ARCH_ROCKCHIP |
---|
591 | 876 | { |
---|
592 | | - const char *s = boot_command_line; |
---|
593 | | - const char *e = &boot_command_line[strlen(boot_command_line)]; |
---|
| 877 | + const char *s = saved_command_line; |
---|
| 878 | + const char *e = &saved_command_line[strlen(saved_command_line)]; |
---|
594 | 879 | int n = |
---|
595 | | - pr_notice("Kernel command line: %s\n", boot_command_line); |
---|
| 880 | + pr_notice("Kernel command line: %s\n", saved_command_line); |
---|
596 | 881 | n -= strlen("Kernel command line: "); |
---|
597 | 882 | s += n; |
---|
598 | 883 | /* command line maybe too long to print one time */ |
---|
.. | .. |
---|
602 | 887 | } |
---|
603 | 888 | } |
---|
604 | 889 | #else |
---|
605 | | - pr_notice("Kernel command line: %s\n", boot_command_line); |
---|
| 890 | + pr_notice("Kernel command line: %s\n", saved_command_line); |
---|
606 | 891 | #endif |
---|
607 | 892 | /* parameters may set static keys */ |
---|
608 | 893 | jump_label_init(); |
---|
.. | .. |
---|
614 | 899 | if (!IS_ERR_OR_NULL(after_dashes)) |
---|
615 | 900 | parse_args("Setting init args", after_dashes, NULL, 0, -1, -1, |
---|
616 | 901 | NULL, set_init_arg); |
---|
| 902 | + if (extra_init_args) |
---|
| 903 | + parse_args("Setting extra init args", extra_init_args, |
---|
| 904 | + NULL, 0, -1, -1, NULL, set_init_arg); |
---|
617 | 905 | |
---|
618 | 906 | /* |
---|
619 | 907 | * These use large bootmem allocations and must precede |
---|
.. | .. |
---|
624 | 912 | sort_main_extable(); |
---|
625 | 913 | trap_init(); |
---|
626 | 914 | mm_init(); |
---|
627 | | - |
---|
| 915 | + poking_init(); |
---|
628 | 916 | ftrace_init(); |
---|
629 | 917 | |
---|
630 | 918 | /* trace_printk can be enabled here */ |
---|
.. | .. |
---|
636 | 924 | * time - but meanwhile we still have a functioning scheduler. |
---|
637 | 925 | */ |
---|
638 | 926 | sched_init(); |
---|
639 | | - /* |
---|
640 | | - * Disable preemption - early bootup scheduling is extremely |
---|
641 | | - * fragile until we cpu_idle() for the first time. |
---|
642 | | - */ |
---|
643 | | - preempt_disable(); |
---|
| 927 | + |
---|
644 | 928 | if (WARN(!irqs_disabled(), |
---|
645 | 929 | "Interrupts were enabled *very* early, fixing it\n")) |
---|
646 | 930 | local_irq_disable(); |
---|
.. | .. |
---|
677 | 961 | hrtimers_init(); |
---|
678 | 962 | softirq_init(); |
---|
679 | 963 | timekeeping_init(); |
---|
| 964 | + kfence_init(); |
---|
| 965 | + time_init(); |
---|
680 | 966 | |
---|
681 | 967 | /* |
---|
682 | 968 | * For best initial stack canary entropy, prepare it after: |
---|
683 | 969 | * - setup_arch() for any UEFI RNG entropy and boot cmdline access |
---|
684 | | - * - timekeeping_init() for ktime entropy used in rand_initialize() |
---|
685 | | - * - rand_initialize() to get any arch-specific entropy like RDRAND |
---|
686 | | - * - add_latent_entropy() to get any latent entropy |
---|
687 | | - * - adding command line entropy |
---|
| 970 | + * - timekeeping_init() for ktime entropy used in random_init() |
---|
| 971 | + * - time_init() for making random_get_entropy() work on some platforms |
---|
| 972 | + * - random_init() to initialize the RNG from from early entropy sources |
---|
688 | 973 | */ |
---|
689 | | - rand_initialize(); |
---|
690 | | - add_latent_entropy(); |
---|
691 | | - add_device_randomness(command_line, strlen(command_line)); |
---|
| 974 | + random_init(command_line); |
---|
692 | 975 | boot_init_stack_canary(); |
---|
693 | 976 | |
---|
694 | | - time_init(); |
---|
695 | 977 | perf_event_init(); |
---|
696 | 978 | profile_init(); |
---|
697 | 979 | call_function_init(); |
---|
.. | .. |
---|
721 | 1003 | */ |
---|
722 | 1004 | locking_selftest(); |
---|
723 | 1005 | |
---|
724 | | - /* |
---|
725 | | - * This needs to be called before any devices perform DMA |
---|
726 | | - * operations that might use the SWIOTLB bounce buffers. It will |
---|
727 | | - * mark the bounce buffers as decrypted so that their usage will |
---|
728 | | - * not cause "plain-text" data to be decrypted when accessed. |
---|
729 | | - */ |
---|
730 | | - mem_encrypt_init(); |
---|
731 | | - |
---|
732 | 1006 | #ifdef CONFIG_BLK_DEV_INITRD |
---|
733 | 1007 | if (initrd_start && !initrd_below_start_ok && |
---|
734 | 1008 | page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) { |
---|
.. | .. |
---|
738 | 1012 | initrd_start = 0; |
---|
739 | 1013 | } |
---|
740 | 1014 | #endif |
---|
741 | | - kmemleak_init(); |
---|
742 | | - debug_objects_mem_init(); |
---|
743 | 1015 | setup_per_cpu_pageset(); |
---|
744 | 1016 | numa_policy_init(); |
---|
745 | 1017 | acpi_early_init(); |
---|
.. | .. |
---|
747 | 1019 | late_time_init(); |
---|
748 | 1020 | sched_clock_init(); |
---|
749 | 1021 | calibrate_delay(); |
---|
| 1022 | + |
---|
| 1023 | + arch_cpu_finalize_init(); |
---|
| 1024 | + |
---|
750 | 1025 | pid_idr_init(); |
---|
751 | 1026 | anon_vma_init(); |
---|
752 | 1027 | #ifdef CONFIG_X86 |
---|
.. | .. |
---|
773 | 1048 | taskstats_init_early(); |
---|
774 | 1049 | delayacct_init(); |
---|
775 | 1050 | |
---|
776 | | - check_bugs(); |
---|
777 | | - |
---|
778 | 1051 | acpi_subsystem_init(); |
---|
779 | 1052 | arch_post_acpi_subsys_init(); |
---|
780 | 1053 | sfi_init_late(); |
---|
781 | | - |
---|
782 | | - if (efi_enabled(EFI_RUNTIME_SERVICES)) { |
---|
783 | | - efi_free_boot_services(); |
---|
784 | | - } |
---|
| 1054 | + kcsan_init(); |
---|
785 | 1055 | |
---|
786 | 1056 | /* Do the rest non-__init'ed, we're now alive */ |
---|
787 | | - rest_init(); |
---|
| 1057 | + arch_call_rest_init(); |
---|
788 | 1058 | |
---|
789 | 1059 | prevent_tail_call_optimization(); |
---|
790 | 1060 | } |
---|
.. | .. |
---|
818 | 1088 | str_entry = strsep(&str, ","); |
---|
819 | 1089 | if (str_entry) { |
---|
820 | 1090 | pr_debug("blacklisting initcall %s\n", str_entry); |
---|
821 | | - entry = alloc_bootmem(sizeof(*entry)); |
---|
822 | | - entry->buf = alloc_bootmem(strlen(str_entry) + 1); |
---|
| 1091 | + entry = memblock_alloc(sizeof(*entry), |
---|
| 1092 | + SMP_CACHE_BYTES); |
---|
| 1093 | + if (!entry) |
---|
| 1094 | + panic("%s: Failed to allocate %zu bytes\n", |
---|
| 1095 | + __func__, sizeof(*entry)); |
---|
| 1096 | + entry->buf = memblock_alloc(strlen(str_entry) + 1, |
---|
| 1097 | + SMP_CACHE_BYTES); |
---|
| 1098 | + if (!entry->buf) |
---|
| 1099 | + panic("%s: Failed to allocate %zu bytes\n", |
---|
| 1100 | + __func__, strlen(str_entry) + 1); |
---|
823 | 1101 | strcpy(entry->buf, str_entry); |
---|
824 | 1102 | list_add(&entry->next, &blacklisted_initcalls); |
---|
825 | 1103 | } |
---|
826 | 1104 | } while (str_entry); |
---|
827 | 1105 | |
---|
828 | | - return 0; |
---|
| 1106 | + return 1; |
---|
829 | 1107 | } |
---|
830 | 1108 | |
---|
831 | 1109 | static bool __init_or_module initcall_blacklisted(initcall_t fn) |
---|
.. | .. |
---|
874 | 1152 | { |
---|
875 | 1153 | ktime_t *calltime = (ktime_t *)data; |
---|
876 | 1154 | |
---|
877 | | - printk(KERN_DEBUG "calling %pF @ %i\n", fn, task_pid_nr(current)); |
---|
| 1155 | + printk(KERN_DEBUG "calling %pS @ %i\n", fn, task_pid_nr(current)); |
---|
878 | 1156 | *calltime = ktime_get(); |
---|
879 | 1157 | } |
---|
880 | 1158 | |
---|
.. | .. |
---|
888 | 1166 | rettime = ktime_get(); |
---|
889 | 1167 | delta = ktime_sub(rettime, *calltime); |
---|
890 | 1168 | duration = (unsigned long long) ktime_to_ns(delta) >> 10; |
---|
891 | | - printk(KERN_DEBUG "initcall %pF returned %d after %lld usecs\n", |
---|
| 1169 | + printk(KERN_DEBUG "initcall %pS returned %d after %lld usecs\n", |
---|
892 | 1170 | fn, ret, duration); |
---|
893 | 1171 | } |
---|
894 | 1172 | |
---|
.. | .. |
---|
945 | 1223 | strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf)); |
---|
946 | 1224 | local_irq_enable(); |
---|
947 | 1225 | } |
---|
948 | | - WARN(msgbuf[0], "initcall %pF returned with %s\n", fn, msgbuf); |
---|
| 1226 | + WARN(msgbuf[0], "initcall %pS returned with %s\n", fn, msgbuf); |
---|
949 | 1227 | |
---|
950 | 1228 | add_latent_entropy(); |
---|
951 | 1229 | return ret; |
---|
.. | .. |
---|
976 | 1254 | }; |
---|
977 | 1255 | |
---|
978 | 1256 | /* Keep these in sync with initcalls in include/linux/init.h */ |
---|
979 | | -static char *initcall_level_names[] __initdata = { |
---|
| 1257 | +static const char *initcall_level_names[] __initdata = { |
---|
980 | 1258 | "pure", |
---|
981 | 1259 | "core", |
---|
982 | 1260 | "postcore", |
---|
.. | .. |
---|
986 | 1264 | "device", |
---|
987 | 1265 | "late", |
---|
988 | 1266 | }; |
---|
| 1267 | + |
---|
| 1268 | +static int __init ignore_unknown_bootoption(char *param, char *val, |
---|
| 1269 | + const char *unused, void *arg) |
---|
| 1270 | +{ |
---|
| 1271 | + return 0; |
---|
| 1272 | +} |
---|
989 | 1273 | |
---|
990 | 1274 | #ifdef CONFIG_INITCALL_ASYNC |
---|
991 | 1275 | extern initcall_entry_t __initcall0s_start[]; |
---|
.. | .. |
---|
1164 | 1448 | } |
---|
1165 | 1449 | #endif /* CONFIG_INITCALL_ASYNC */ |
---|
1166 | 1450 | |
---|
1167 | | -static void __init do_initcall_level(int level) |
---|
| 1451 | +static void __init do_initcall_level(int level, char *command_line) |
---|
1168 | 1452 | { |
---|
1169 | 1453 | initcall_entry_t *fn; |
---|
1170 | 1454 | |
---|
1171 | | - strcpy(initcall_command_line, saved_command_line); |
---|
1172 | 1455 | parse_args(initcall_level_names[level], |
---|
1173 | | - initcall_command_line, __start___param, |
---|
| 1456 | + command_line, __start___param, |
---|
1174 | 1457 | __stop___param - __start___param, |
---|
1175 | 1458 | level, level, |
---|
1176 | | - NULL, &repair_env_string); |
---|
| 1459 | + NULL, ignore_unknown_bootoption); |
---|
1177 | 1460 | |
---|
1178 | 1461 | trace_initcall_level(initcall_level_names[level]); |
---|
1179 | 1462 | |
---|
.. | .. |
---|
1190 | 1473 | static void __init do_initcalls(void) |
---|
1191 | 1474 | { |
---|
1192 | 1475 | int level; |
---|
| 1476 | + size_t len = strlen(saved_command_line) + 1; |
---|
| 1477 | + char *command_line; |
---|
1193 | 1478 | |
---|
1194 | 1479 | #ifdef CONFIG_INITCALL_ASYNC |
---|
1195 | 1480 | initcall_init_workers(); |
---|
1196 | 1481 | #endif |
---|
1197 | 1482 | |
---|
1198 | | - for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) |
---|
1199 | | - do_initcall_level(level); |
---|
| 1483 | + command_line = kzalloc(len, GFP_KERNEL); |
---|
| 1484 | + if (!command_line) |
---|
| 1485 | + panic("%s: Failed to allocate %zu bytes\n", __func__, len); |
---|
| 1486 | + |
---|
| 1487 | + for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) { |
---|
| 1488 | + /* Parser modifies command_line, restore it each time */ |
---|
| 1489 | + strcpy(command_line, saved_command_line); |
---|
| 1490 | + do_initcall_level(level, command_line); |
---|
| 1491 | + } |
---|
| 1492 | + |
---|
| 1493 | + kfree(command_line); |
---|
1200 | 1494 | |
---|
1201 | 1495 | #ifdef CONFIG_INITCALL_ASYNC |
---|
1202 | 1496 | initcall_free_works(); |
---|
.. | .. |
---|
1213 | 1507 | static void __init do_basic_setup(void) |
---|
1214 | 1508 | { |
---|
1215 | 1509 | cpuset_init_smp(); |
---|
1216 | | - shmem_init(); |
---|
1217 | 1510 | driver_init(); |
---|
1218 | 1511 | init_irq_proc(); |
---|
1219 | 1512 | do_ctors(); |
---|
.. | .. |
---|
1230 | 1523 | do_one_initcall(initcall_from_entry(fn)); |
---|
1231 | 1524 | } |
---|
1232 | 1525 | |
---|
1233 | | -/* |
---|
1234 | | - * This function requests modules which should be loaded by default and is |
---|
1235 | | - * called twice right after initrd is mounted and right before init is |
---|
1236 | | - * exec'd. If such modules are on either initrd or rootfs, they will be |
---|
1237 | | - * loaded before control is passed to userland. |
---|
1238 | | - */ |
---|
1239 | | -void __init load_default_modules(void) |
---|
1240 | | -{ |
---|
1241 | | - load_default_elevator_module(); |
---|
1242 | | -} |
---|
1243 | | - |
---|
1244 | 1526 | static int run_init_process(const char *init_filename) |
---|
1245 | 1527 | { |
---|
| 1528 | + const char *const *p; |
---|
| 1529 | + |
---|
1246 | 1530 | argv_init[0] = init_filename; |
---|
1247 | 1531 | pr_info("Run %s as init process\n", init_filename); |
---|
1248 | | - return do_execve(getname_kernel(init_filename), |
---|
1249 | | - (const char __user *const __user *)argv_init, |
---|
1250 | | - (const char __user *const __user *)envp_init); |
---|
| 1532 | + pr_debug(" with arguments:\n"); |
---|
| 1533 | + for (p = argv_init; *p; p++) |
---|
| 1534 | + pr_debug(" %s\n", *p); |
---|
| 1535 | + pr_debug(" with environment:\n"); |
---|
| 1536 | + for (p = envp_init; *p; p++) |
---|
| 1537 | + pr_debug(" %s\n", *p); |
---|
| 1538 | + return kernel_execve(init_filename, argv_init, envp_init); |
---|
1251 | 1539 | } |
---|
1252 | 1540 | |
---|
1253 | 1541 | static int try_to_run_init_process(const char *init_filename) |
---|
.. | .. |
---|
1270 | 1558 | bool rodata_enabled __ro_after_init = true; |
---|
1271 | 1559 | static int __init set_debug_rodata(char *str) |
---|
1272 | 1560 | { |
---|
1273 | | - return strtobool(str, &rodata_enabled); |
---|
| 1561 | + if (strtobool(str, &rodata_enabled)) |
---|
| 1562 | + pr_warn("Invalid option string for rodata: '%s'\n", str); |
---|
| 1563 | + return 1; |
---|
1274 | 1564 | } |
---|
1275 | 1565 | __setup("rodata=", set_debug_rodata); |
---|
1276 | 1566 | #endif |
---|
.. | .. |
---|
1280 | 1570 | { |
---|
1281 | 1571 | if (rodata_enabled) { |
---|
1282 | 1572 | /* |
---|
1283 | | - * load_module() results in W+X mappings, which are cleaned up |
---|
1284 | | - * with call_rcu_sched(). Let's make sure that queued work is |
---|
| 1573 | + * load_module() results in W+X mappings, which are cleaned |
---|
| 1574 | + * up with call_rcu(). Let's make sure that queued work is |
---|
1285 | 1575 | * flushed so that we don't hit false positives looking for |
---|
1286 | 1576 | * insecure pages which are W+X. |
---|
1287 | 1577 | */ |
---|
1288 | | - rcu_barrier_sched(); |
---|
| 1578 | + rcu_barrier(); |
---|
1289 | 1579 | mark_rodata_ro(); |
---|
1290 | 1580 | rodata_test(); |
---|
1291 | 1581 | } else |
---|
1292 | 1582 | pr_info("Kernel memory protection disabled.\n"); |
---|
| 1583 | +} |
---|
| 1584 | +#elif defined(CONFIG_ARCH_HAS_STRICT_KERNEL_RWX) |
---|
| 1585 | +static inline void mark_readonly(void) |
---|
| 1586 | +{ |
---|
| 1587 | + pr_warn("Kernel memory protection not selected by kernel config.\n"); |
---|
1293 | 1588 | } |
---|
1294 | 1589 | #else |
---|
1295 | 1590 | static inline void mark_readonly(void) |
---|
.. | .. |
---|
1298 | 1593 | } |
---|
1299 | 1594 | #endif |
---|
1300 | 1595 | |
---|
| 1596 | +void __weak free_initmem(void) |
---|
| 1597 | +{ |
---|
| 1598 | + free_initmem_default(POISON_FREE_INITMEM); |
---|
| 1599 | +} |
---|
| 1600 | + |
---|
1301 | 1601 | static int __ref kernel_init(void *unused) |
---|
1302 | 1602 | { |
---|
1303 | 1603 | int ret; |
---|
.. | .. |
---|
1305 | 1605 | kernel_init_freeable(); |
---|
1306 | 1606 | /* need to finish all async __init code before freeing the memory */ |
---|
1307 | 1607 | async_synchronize_full(); |
---|
| 1608 | + kprobe_free_init_mem(); |
---|
1308 | 1609 | ftrace_free_init_mem(); |
---|
1309 | | - jump_label_invalidate_initmem(); |
---|
| 1610 | + kgdb_free_init_mem(); |
---|
1310 | 1611 | free_initmem(); |
---|
1311 | 1612 | mark_readonly(); |
---|
1312 | 1613 | |
---|
.. | .. |
---|
1320 | 1621 | numa_default_policy(); |
---|
1321 | 1622 | |
---|
1322 | 1623 | rcu_end_inkernel_boot(); |
---|
| 1624 | + |
---|
| 1625 | + do_sysctl_args(); |
---|
1323 | 1626 | |
---|
1324 | 1627 | if (ramdisk_execute_command) { |
---|
1325 | 1628 | ret = run_init_process(ramdisk_execute_command); |
---|
.. | .. |
---|
1342 | 1645 | panic("Requested init %s failed (error %d).", |
---|
1343 | 1646 | execute_command, ret); |
---|
1344 | 1647 | } |
---|
| 1648 | + |
---|
| 1649 | + if (CONFIG_DEFAULT_INIT[0] != '\0') { |
---|
| 1650 | + ret = run_init_process(CONFIG_DEFAULT_INIT); |
---|
| 1651 | + if (ret) |
---|
| 1652 | + pr_err("Default init %s failed (error %d)\n", |
---|
| 1653 | + CONFIG_DEFAULT_INIT, ret); |
---|
| 1654 | + else |
---|
| 1655 | + return 0; |
---|
| 1656 | + } |
---|
| 1657 | + |
---|
1345 | 1658 | if (!try_to_run_init_process("/sbin/init") || |
---|
1346 | 1659 | !try_to_run_init_process("/etc/init") || |
---|
1347 | 1660 | !try_to_run_init_process("/bin/init") || |
---|
.. | .. |
---|
1350 | 1663 | |
---|
1351 | 1664 | panic("No working init found. Try passing init= option to kernel. " |
---|
1352 | 1665 | "See Linux Documentation/admin-guide/init.rst for guidance."); |
---|
| 1666 | +} |
---|
| 1667 | + |
---|
| 1668 | +/* Open /dev/console, for stdin/stdout/stderr, this should never fail */ |
---|
| 1669 | +void __init console_on_rootfs(void) |
---|
| 1670 | +{ |
---|
| 1671 | + struct file *file = filp_open("/dev/console", O_RDWR, 0); |
---|
| 1672 | + |
---|
| 1673 | + if (IS_ERR(file)) { |
---|
| 1674 | + pr_err("Warning: unable to open an initial console.\n"); |
---|
| 1675 | + return; |
---|
| 1676 | + } |
---|
| 1677 | + init_dup(file); |
---|
| 1678 | + init_dup(file); |
---|
| 1679 | + init_dup(file); |
---|
| 1680 | + fput(file); |
---|
1353 | 1681 | } |
---|
1354 | 1682 | |
---|
1355 | 1683 | static noinline void __init kernel_init_freeable(void) |
---|
.. | .. |
---|
1375 | 1703 | |
---|
1376 | 1704 | init_mm_internals(); |
---|
1377 | 1705 | |
---|
| 1706 | + rcu_init_tasks_generic(); |
---|
1378 | 1707 | do_pre_smp_initcalls(); |
---|
1379 | 1708 | lockup_detector_init(); |
---|
1380 | 1709 | |
---|
1381 | 1710 | smp_init(); |
---|
1382 | 1711 | sched_init_smp(); |
---|
1383 | 1712 | |
---|
1384 | | -#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT |
---|
1385 | | - kthread_run(defer_free_bootmem, NULL, "defer_mem"); |
---|
| 1713 | +#if defined(CONFIG_ROCKCHIP_THUNDER_BOOT) && defined(CONFIG_SMP) |
---|
| 1714 | + kthread_run(defer_free_memblock, NULL, "defer_mem"); |
---|
1386 | 1715 | #endif |
---|
1387 | 1716 | |
---|
| 1717 | + padata_init(); |
---|
1388 | 1718 | page_alloc_init_late(); |
---|
1389 | 1719 | /* Initialize page ext after all struct pages are initialized. */ |
---|
1390 | 1720 | page_ext_init(); |
---|
1391 | 1721 | |
---|
1392 | 1722 | do_basic_setup(); |
---|
1393 | 1723 | |
---|
| 1724 | + kunit_run_all_tests(); |
---|
| 1725 | + |
---|
1394 | 1726 | #if IS_BUILTIN(CONFIG_INITRD_ASYNC) |
---|
1395 | 1727 | async_synchronize_full(); |
---|
1396 | 1728 | #endif |
---|
1397 | 1729 | |
---|
1398 | | - /* Open the /dev/console on the rootfs, this should never fail */ |
---|
1399 | | - if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) |
---|
1400 | | - pr_err("Warning: unable to open an initial console.\n"); |
---|
| 1730 | + console_on_rootfs(); |
---|
1401 | 1731 | |
---|
1402 | | - (void) ksys_dup(0); |
---|
1403 | | - (void) ksys_dup(0); |
---|
1404 | 1732 | /* |
---|
1405 | 1733 | * check if there is an early userspace init. If yes, let it do all |
---|
1406 | 1734 | * the work |
---|
1407 | 1735 | */ |
---|
1408 | | - |
---|
1409 | | - if (!ramdisk_execute_command) |
---|
1410 | | - ramdisk_execute_command = "/init"; |
---|
1411 | | - |
---|
1412 | | - if (ksys_access((const char __user *) |
---|
1413 | | - ramdisk_execute_command, 0) != 0) { |
---|
| 1736 | + if (init_eaccess(ramdisk_execute_command) != 0) { |
---|
1414 | 1737 | ramdisk_execute_command = NULL; |
---|
1415 | 1738 | prepare_namespace(); |
---|
1416 | 1739 | } |
---|
.. | .. |
---|
1425 | 1748 | */ |
---|
1426 | 1749 | |
---|
1427 | 1750 | integrity_load_keys(); |
---|
1428 | | - load_default_modules(); |
---|
1429 | 1751 | } |
---|