arm64/efi: move arm64 specific stub C code to libstub
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Fri, 23 Oct 2015 14:48:14 +0000 (16:48 +0200)
committerCatalin Marinas <catalin.marinas@arm.com>
Fri, 30 Oct 2015 16:02:52 +0000 (16:02 +0000)
Now that we added special handling to the C files in libstub, move
the one remaining arm64 specific EFI stub C file to libstub as
well, so that it gets the same treatment. This should prevent future
changes from resulting in binaries that may execute incorrectly in
UEFI context.

With efi-entry.S the only remaining EFI stub source file under
arch/arm64, we can also simplify the Makefile logic somewhat.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
Tested-by: Jeremy Linton <jeremy.linton@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/kernel/Makefile
arch/arm64/kernel/efi-stub.c [deleted file]
drivers/firmware/efi/libstub/Makefile
drivers/firmware/efi/libstub/arm64-stub.c [new file with mode: 0644]

index 1b6bda2ff102a0e90ccd94ff1ad49d89c40f32df..474691f8b13ab893cf403b8c1737a91aeff87bc0 100644 (file)
@@ -4,11 +4,8 @@
 
 CPPFLAGS_vmlinux.lds   := -DTEXT_OFFSET=$(TEXT_OFFSET)
 AFLAGS_head.o          := -DTEXT_OFFSET=$(TEXT_OFFSET)
-CFLAGS_efi-stub.o      := -DTEXT_OFFSET=$(TEXT_OFFSET)
 CFLAGS_armv8_deprecated.o := -I$(src)
 
-KASAN_SANITIZE_efi-stub.o      := n
-
 CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_insn.o = -pg
 CFLAGS_REMOVE_return_address.o = -pg
@@ -22,9 +19,7 @@ arm64-obj-y           := debug-monitors.o entry.o irq.o fpsimd.o              \
                           cpufeature.o alternative.o cacheinfo.o               \
                           smp.o smp_spin_table.o topology.o
 
-stub-obj                               := efi-stub.o efi-entry.o
-extra-y                                        := $(stub-obj)
-stub-obj                               := $(patsubst %.o,%.stub.o,$(stub-obj))
+extra-$(CONFIG_EFI)                    := efi-entry.o
 
 OBJCOPYFLAGS := --prefix-symbols=__efistub_
 $(obj)/%.stub.o: $(obj)/%.o FORCE
@@ -42,7 +37,7 @@ arm64-obj-$(CONFIG_CPU_PM)            += sleep.o suspend.o
 arm64-obj-$(CONFIG_CPU_IDLE)           += cpuidle.o
 arm64-obj-$(CONFIG_JUMP_LABEL)         += jump_label.o
 arm64-obj-$(CONFIG_KGDB)               += kgdb.o
-arm64-obj-$(CONFIG_EFI)                        += efi.o $(stub-obj)
+arm64-obj-$(CONFIG_EFI)                        += efi.o efi-entry.stub.o
 arm64-obj-$(CONFIG_PCI)                        += pci.o
 arm64-obj-$(CONFIG_ARMV8_DEPRECATED)   += armv8_deprecated.o
 arm64-obj-$(CONFIG_ACPI)               += acpi.o
diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
deleted file mode 100644 (file)
index 816120e..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2013, 2014 Linaro Ltd;  <roy.franz@linaro.org>
- *
- * This file implements the EFI boot stub for the arm64 kernel.
- * Adapted from ARM version by Mark Salter <msalter@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <linux/efi.h>
-#include <asm/efi.h>
-#include <asm/sections.h>
-
-efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
-                                       unsigned long *image_addr,
-                                       unsigned long *image_size,
-                                       unsigned long *reserve_addr,
-                                       unsigned long *reserve_size,
-                                       unsigned long dram_base,
-                                       efi_loaded_image_t *image)
-{
-       efi_status_t status;
-       unsigned long kernel_size, kernel_memsize = 0;
-       unsigned long nr_pages;
-       void *old_image_addr = (void *)*image_addr;
-
-       /* Relocate the image, if required. */
-       kernel_size = _edata - _text;
-       if (*image_addr != (dram_base + TEXT_OFFSET)) {
-               kernel_memsize = kernel_size + (_end - _edata);
-
-               /*
-                * First, try a straight allocation at the preferred offset.
-                * This will work around the issue where, if dram_base == 0x0,
-                * efi_low_alloc() refuses to allocate at 0x0 (to prevent the
-                * address of the allocation to be mistaken for a FAIL return
-                * value or a NULL pointer). It will also ensure that, on
-                * platforms where the [dram_base, dram_base + TEXT_OFFSET)
-                * interval is partially occupied by the firmware (like on APM
-                * Mustang), we can still place the kernel at the address
-                * 'dram_base + TEXT_OFFSET'.
-                */
-               *image_addr = *reserve_addr = dram_base + TEXT_OFFSET;
-               nr_pages = round_up(kernel_memsize, EFI_ALLOC_ALIGN) /
-                          EFI_PAGE_SIZE;
-               status = efi_call_early(allocate_pages, EFI_ALLOCATE_ADDRESS,
-                                       EFI_LOADER_DATA, nr_pages,
-                                       (efi_physical_addr_t *)reserve_addr);
-               if (status != EFI_SUCCESS) {
-                       kernel_memsize += TEXT_OFFSET;
-                       status = efi_low_alloc(sys_table_arg, kernel_memsize,
-                                              SZ_2M, reserve_addr);
-
-                       if (status != EFI_SUCCESS) {
-                               pr_efi_err(sys_table_arg, "Failed to relocate kernel\n");
-                               return status;
-                       }
-                       *image_addr = *reserve_addr + TEXT_OFFSET;
-               }
-               memcpy((void *)*image_addr, old_image_addr, kernel_size);
-               *reserve_size = kernel_memsize;
-       }
-
-
-       return EFI_SUCCESS;
-}
index bca9a76cbd332bace4d303457010b64eaa3d2b5f..92ae557abbbcaf09769a4d52e550b3cbb73cd00b 100644 (file)
@@ -34,6 +34,9 @@ $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 lib-$(CONFIG_EFI_ARMSTUB)      += arm-stub.o fdt.o string.o \
                                   $(patsubst %.c,lib-%.o,$(arm-deps))
 
+lib-$(CONFIG_ARM64)            += arm64-stub.o
+CFLAGS_arm64-stub.o            := -DTEXT_OFFSET=$(TEXT_OFFSET)
+
 #
 # arm64 puts the stub in the kernel proper, which will unnecessarily retain all
 # code indefinitely unless it is annotated as __init/__initdata/__initconst etc.
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
new file mode 100644 (file)
index 0000000..816120e
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2013, 2014 Linaro Ltd;  <roy.franz@linaro.org>
+ *
+ * This file implements the EFI boot stub for the arm64 kernel.
+ * Adapted from ARM version by Mark Salter <msalter@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/efi.h>
+#include <asm/efi.h>
+#include <asm/sections.h>
+
+efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
+                                       unsigned long *image_addr,
+                                       unsigned long *image_size,
+                                       unsigned long *reserve_addr,
+                                       unsigned long *reserve_size,
+                                       unsigned long dram_base,
+                                       efi_loaded_image_t *image)
+{
+       efi_status_t status;
+       unsigned long kernel_size, kernel_memsize = 0;
+       unsigned long nr_pages;
+       void *old_image_addr = (void *)*image_addr;
+
+       /* Relocate the image, if required. */
+       kernel_size = _edata - _text;
+       if (*image_addr != (dram_base + TEXT_OFFSET)) {
+               kernel_memsize = kernel_size + (_end - _edata);
+
+               /*
+                * First, try a straight allocation at the preferred offset.
+                * This will work around the issue where, if dram_base == 0x0,
+                * efi_low_alloc() refuses to allocate at 0x0 (to prevent the
+                * address of the allocation to be mistaken for a FAIL return
+                * value or a NULL pointer). It will also ensure that, on
+                * platforms where the [dram_base, dram_base + TEXT_OFFSET)
+                * interval is partially occupied by the firmware (like on APM
+                * Mustang), we can still place the kernel at the address
+                * 'dram_base + TEXT_OFFSET'.
+                */
+               *image_addr = *reserve_addr = dram_base + TEXT_OFFSET;
+               nr_pages = round_up(kernel_memsize, EFI_ALLOC_ALIGN) /
+                          EFI_PAGE_SIZE;
+               status = efi_call_early(allocate_pages, EFI_ALLOCATE_ADDRESS,
+                                       EFI_LOADER_DATA, nr_pages,
+                                       (efi_physical_addr_t *)reserve_addr);
+               if (status != EFI_SUCCESS) {
+                       kernel_memsize += TEXT_OFFSET;
+                       status = efi_low_alloc(sys_table_arg, kernel_memsize,
+                                              SZ_2M, reserve_addr);
+
+                       if (status != EFI_SUCCESS) {
+                               pr_efi_err(sys_table_arg, "Failed to relocate kernel\n");
+                               return status;
+                       }
+                       *image_addr = *reserve_addr + TEXT_OFFSET;
+               }
+               memcpy((void *)*image_addr, old_image_addr, kernel_size);
+               *reserve_size = kernel_memsize;
+       }
+
+
+       return EFI_SUCCESS;
+}