um: Extract load file helper from initrd.c
authorVincent Whitchurch <vincent.whitchurch@axis.com>
Wed, 8 Dec 2021 15:11:22 +0000 (16:11 +0100)
committerRichard Weinberger <richard@nod.at>
Wed, 22 Dec 2021 19:32:36 +0000 (20:32 +0100)
The file loading support in initrd.c can be re-used for
loading devicetrees.  Move it out of initrd.c.

Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
arch/um/kernel/Makefile
arch/um/kernel/initrd.c
arch/um/kernel/load_file.c [new file with mode: 0644]
arch/um/kernel/um_arch.h [new file with mode: 0644]

index 7ab6d40..4ab4a00 100644 (file)
@@ -18,6 +18,7 @@ obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \
        physmem.o process.o ptrace.o reboot.o sigio.o \
        signal.o sysrq.o time.o tlb.o trap.o \
        um_arch.o umid.o maccess.o kmsg_dump.o capflags.o skas/
+obj-y += load_file.o
 
 obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
 obj-$(CONFIG_GPROF)    += gprof_syms.o
index c1981ff..47b8cb1 100644 (file)
 #include <init.h>
 #include <os.h>
 
+#include "um_arch.h"
+
 /* Changed by uml_initrd_setup, which is a setup */
 static char *initrd __initdata = NULL;
-static int load_initrd(char *filename, void *buf, int size);
 
 int __init read_initrd(void)
 {
+       unsigned long long size;
        void *area;
-       long long size;
-       int err;
-
-       if (initrd == NULL)
-               return 0;
 
-       err = os_file_size(initrd, &size);
-       if (err)
+       if (!initrd)
                return 0;
 
-       /*
-        * This is necessary because alloc_bootmem craps out if you
-        * ask for no memory.
-        */
-       if (size == 0) {
-               printk(KERN_ERR "\"%s\" is a zero-size initrd\n", initrd);
-               return 0;
-       }
-
-       area = memblock_alloc(size, SMP_CACHE_BYTES);
+       area = uml_load_file(initrd, &size);
        if (!area)
-               panic("%s: Failed to allocate %llu bytes\n", __func__, size);
-
-       if (load_initrd(initrd, area, size) == -1)
                return 0;
 
        initrd_start = (unsigned long) area;
@@ -59,25 +43,3 @@ __uml_setup("initrd=", uml_initrd_setup,
 "    This is used to boot UML from an initrd image.  The argument is the\n"
 "    name of the file containing the image.\n\n"
 );
-
-static int load_initrd(char *filename, void *buf, int size)
-{
-       int fd, n;
-
-       fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
-       if (fd < 0) {
-               printk(KERN_ERR "Opening '%s' failed - err = %d\n", filename,
-                      -fd);
-               return -1;
-       }
-       n = os_read_file(fd, buf, size);
-       if (n != size) {
-               printk(KERN_ERR "Read of %d bytes from '%s' failed, "
-                      "err = %d\n", size,
-                      filename, -n);
-               return -1;
-       }
-
-       os_close_file(fd);
-       return 0;
-}
diff --git a/arch/um/kernel/load_file.c b/arch/um/kernel/load_file.c
new file mode 100644 (file)
index 0000000..5cecd0e
--- /dev/null
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ */
+#include <linux/memblock.h>
+#include <os.h>
+
+#include "um_arch.h"
+
+static int __init __uml_load_file(const char *filename, void *buf, int size)
+{
+       int fd, n;
+
+       fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
+       if (fd < 0) {
+               printk(KERN_ERR "Opening '%s' failed - err = %d\n", filename,
+                      -fd);
+               return -1;
+       }
+       n = os_read_file(fd, buf, size);
+       if (n != size) {
+               printk(KERN_ERR "Read of %d bytes from '%s' failed, "
+                      "err = %d\n", size,
+                      filename, -n);
+               return -1;
+       }
+
+       os_close_file(fd);
+       return 0;
+}
+
+void *uml_load_file(const char *filename, unsigned long long *size)
+{
+       void *area;
+       int err;
+
+       *size = 0;
+
+       if (!filename)
+               return NULL;
+
+       err = os_file_size(filename, size);
+       if (err)
+               return NULL;
+
+       if (*size == 0) {
+               printk(KERN_ERR "\"%s\" is empty\n", filename);
+               return NULL;
+       }
+
+       area = memblock_alloc(*size, SMP_CACHE_BYTES);
+       if (!area)
+               panic("%s: Failed to allocate %llu bytes\n", __func__, *size);
+
+       if (__uml_load_file(filename, area, *size)) {
+               memblock_free(area, *size);
+               return NULL;
+       }
+
+       return area;
+}
diff --git a/arch/um/kernel/um_arch.h b/arch/um/kernel/um_arch.h
new file mode 100644 (file)
index 0000000..b195df3
--- /dev/null
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __UML_ARCH_H__
+#define __UML_ARCH_H__
+
+extern void * __init uml_load_file(const char *filename, unsigned long long *size);
+
+#endif