aboutsummaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
Diffstat (limited to 'init')
-rw-r--r--init/Kconfig9
-rw-r--r--init/do_mounts.c17
-rw-r--r--init/initramfs.c47
-rw-r--r--init/main.c49
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");