diff options
Diffstat (limited to 'init')
-rw-r--r-- | init/Kconfig | 9 | ||||
-rw-r--r-- | init/do_mounts.c | 17 | ||||
-rw-r--r-- | init/initramfs.c | 47 | ||||
-rw-r--r-- | init/main.c | 49 |
4 files changed, 72 insertions, 50 deletions
diff --git a/init/Kconfig b/init/Kconfig index e6216dc2a1d1..f641518f4ac5 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -33,6 +33,15 @@ config CC_CAN_LINK config CC_HAS_ASM_GOTO def_bool $(success,$(srctree)/scripts/gcc-goto.sh $(CC)) +config CC_HAS_ASM_GOTO_TIED_OUTPUT + depends on CC_HAS_ASM_GOTO_OUTPUT + # Detect buggy gcc and clang, fixed in gcc-11 clang-14. + def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null) + +config CC_HAS_ASM_GOTO_OUTPUT + depends on CC_HAS_ASM_GOTO + def_bool $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null) + config TOOLS_SUPPORT_RELR def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh) diff --git a/init/do_mounts.c b/init/do_mounts.c index 9634ecf3743d..69a08cf36545 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -440,7 +440,9 @@ retry: printk("DEBUG_BLOCK_EXT_DEVT is enabled, you need to specify " "explicit textual name for \"root=\" boot option.\n"); #endif - panic("VFS: Unable to mount root fs on %s", b); + printk(KERN_EMERG "VFS: Unable to mount root fs on %s\n", b); + printk(KERN_EMERG "User configuration error - no valid root filesystem found\n"); + panic("Invalid configuration from end user prevents continuing"); } if (!(flags & SB_RDONLY)) { flags |= SB_RDONLY; @@ -456,7 +458,9 @@ retry: #ifdef CONFIG_BLOCK __bdevname(ROOT_DEV, b); #endif - panic("VFS: Unable to mount root fs on %s", b); + printk(KERN_EMERG "VFS: Unable to mount root fs on %s\n", b); + printk(KERN_EMERG "User configuration error - no valid root filesystem found\n"); + panic("Invalid configuration from end user prevents continuing"); out: put_page(page); } @@ -643,7 +647,10 @@ struct file_system_type rootfs_fs_type = { void __init init_rootfs(void) { - if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] && - (!root_fs_names || strstr(root_fs_names, "tmpfs"))) - is_tmpfs = true; + if (IS_ENABLED(CONFIG_TMPFS)) { + if (!saved_root_name[0] && !root_fs_names) + is_tmpfs = true; + else if (root_fs_names && !!strstr(root_fs_names, "tmpfs")) + is_tmpfs = true; + } } diff --git a/init/initramfs.c b/init/initramfs.c index 00a32799a38b..b362b57c047d 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -11,13 +11,14 @@ #include <linux/utime.h> #include <linux/file.h> -static ssize_t __init xwrite(int fd, const char *p, size_t count) +static ssize_t __init xwrite(struct file *file, const char *p, size_t count, + loff_t *pos) { ssize_t out = 0; /* sys_write only can write MAX_RW_COUNT aka 2G-4K bytes at most */ while (count) { - ssize_t rv = ksys_write(fd, p, count); + ssize_t rv = kernel_write(file, p, count, pos); if (rv < 0) { if (rv == -EINTR || rv == -EAGAIN) @@ -315,7 +316,8 @@ static int __init maybe_link(void) return 0; } -static __initdata int wfd; +static __initdata struct file *wfile; +static __initdata loff_t wfile_pos; static int __init do_name(void) { @@ -332,16 +334,17 @@ static int __init do_name(void) int openflags = O_WRONLY|O_CREAT; if (ml != 1) openflags |= O_TRUNC; - wfd = ksys_open(collected, openflags, mode); - - if (wfd >= 0) { - ksys_fchown(wfd, uid, gid); - ksys_fchmod(wfd, mode); - if (body_len) - ksys_ftruncate(wfd, body_len); - vcollected = kstrdup(collected, GFP_KERNEL); - state = CopyFile; - } + wfile = filp_open(collected, openflags, mode); + if (IS_ERR(wfile)) + return 0; + wfile_pos = 0; + + vfs_fchown(wfile, uid, gid); + vfs_fchmod(wfile, mode); + if (body_len) + vfs_truncate(&wfile->f_path, body_len); + vcollected = kstrdup(collected, GFP_KERNEL); + state = CopyFile; } } else if (S_ISDIR(mode)) { ksys_mkdir(collected, mode); @@ -363,16 +366,16 @@ static int __init do_name(void) static int __init do_copy(void) { if (byte_count >= body_len) { - if (xwrite(wfd, victim, body_len) != body_len) + if (xwrite(wfile, victim, body_len, &wfile_pos) != body_len) error("write error"); - ksys_close(wfd); + fput(wfile); do_utime(vcollected, mtime); kfree(vcollected); eat(body_len); state = SkipIt; return 0; } else { - if (xwrite(wfd, victim, byte_count) != byte_count) + if (xwrite(wfile, victim, byte_count, &wfile_pos) != byte_count) error("write error"); body_len -= byte_count; eat(byte_count); @@ -620,21 +623,23 @@ static inline void clean_rootfs(void) static void __init populate_initrd_image(char *err) { ssize_t written; - int fd; + struct file *file; + loff_t pos = 0; unpack_to_rootfs(__initramfs_start, __initramfs_size); printk(KERN_INFO "rootfs image is not initramfs (%s); looks like an initrd\n", err); - fd = ksys_open("/initrd.image", O_WRONLY | O_CREAT, 0700); - if (fd < 0) + file = filp_open("/initrd.image", O_WRONLY|O_CREAT|O_LARGEFILE, 0700); + if (IS_ERR(file)) return; - written = xwrite(fd, (char *)initrd_start, initrd_end - initrd_start); + written = xwrite(file, (char *)initrd_start, initrd_end - initrd_start, + &pos); if (written != initrd_end - initrd_start) pr_err("/initrd.image: incomplete write (%zd != %ld)\n", written, initrd_end - initrd_start); - ksys_close(fd); + fput(file); } #else static void __init populate_initrd_image(char *err) diff --git a/init/main.c b/init/main.c index d292daabd9a2..1c786bd8ca47 100644 --- a/init/main.c +++ b/init/main.c @@ -93,10 +93,8 @@ #include <linux/cache.h> #include <linux/rodata_test.h> #include <linux/jump_label.h> -#include <linux/mem_encrypt.h> #include <asm/io.h> -#include <asm/bugs.h> #include <asm/setup.h> #include <asm/sections.h> #include <asm/cacheflush.h> @@ -504,8 +502,6 @@ void __init __weak thread_stack_cache_init(void) } #endif -void __init __weak mem_encrypt_init(void) { } - void __init __weak poking_init(void) { } void __init __weak pgtable_cache_init(void) { } @@ -567,6 +563,7 @@ static void __init mm_init(void) init_espfix_bsp(); /* Should be run after espfix64 is set up. */ pti_init(); + mm_cache_init(); } void __init __weak arch_call_rest_init(void) @@ -627,7 +624,7 @@ asmlinkage __visible void __init start_kernel(void) sort_main_extable(); trap_init(); mm_init(); - + poking_init(); ftrace_init(); /* trace_printk can be enabled here */ @@ -680,21 +677,18 @@ asmlinkage __visible void __init start_kernel(void) hrtimers_init(); softirq_init(); timekeeping_init(); + time_init(); /* * For best initial stack canary entropy, prepare it after: * - setup_arch() for any UEFI RNG entropy and boot cmdline access - * - timekeeping_init() for ktime entropy used in rand_initialize() - * - rand_initialize() to get any arch-specific entropy like RDRAND - * - add_latent_entropy() to get any latent entropy - * - adding command line entropy + * - timekeeping_init() for ktime entropy used in random_init() + * - time_init() for making random_get_entropy() work on some platforms + * - random_init() to initialize the RNG from from early entropy sources */ - rand_initialize(); - add_latent_entropy(); - add_device_randomness(command_line, strlen(command_line)); + random_init(command_line); boot_init_stack_canary(); - time_init(); perf_event_init(); profile_init(); call_function_init(); @@ -724,14 +718,6 @@ asmlinkage __visible void __init start_kernel(void) */ locking_selftest(); - /* - * This needs to be called before any devices perform DMA - * operations that might use the SWIOTLB bounce buffers. It will - * mark the bounce buffers as decrypted so that their usage will - * not cause "plain-text" data to be decrypted when accessed. - */ - mem_encrypt_init(); - #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && !initrd_below_start_ok && page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) { @@ -748,6 +734,9 @@ asmlinkage __visible void __init start_kernel(void) late_time_init(); sched_clock_init(); calibrate_delay(); + + arch_cpu_finalize_init(); + pid_idr_init(); anon_vma_init(); #ifdef CONFIG_X86 @@ -774,9 +763,6 @@ asmlinkage __visible void __init start_kernel(void) taskstats_init_early(); delayacct_init(); - poking_init(); - check_bugs(); - acpi_subsystem_init(); arch_post_acpi_subsys_init(); sfi_init_late(); @@ -1163,6 +1149,9 @@ static int __ref kernel_init(void *unused) static noinline void __init kernel_init_freeable(void) { +#ifndef CONFIG_BLK_DEV_INITRD + struct kstat console_stat; +#endif /* * Wait until kthreadd is all set-up. */ @@ -1196,6 +1185,18 @@ static noinline void __init kernel_init_freeable(void) do_basic_setup(); +#ifndef CONFIG_BLK_DEV_INITRD + /* + * Use /dev/console to infer if the rootfs is setup properly. + * In case of initrd or initramfs /dev/console might be instantiated + * later by /init so don't do this check for CONFIG_BLK_DEV_INITRD + */ + if (vfs_lstat((char __user *) "/dev/console", (struct kstat __user *) &console_stat) + || !S_ISCHR(console_stat.mode)) { + panic("/dev/console is missing or not a character device!\nPlease ensure your rootfs is properly configured\n"); + } +#endif + /* Open the /dev/console on the rootfs, this should never fail */ if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) pr_err("Warning: unable to open an initial console.\n"); |