]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'v4.10-rc7' into efi/core, to pick up fixes
authorIngo Molnar <mingo@kernel.org>
Tue, 7 Feb 2017 07:49:17 +0000 (08:49 +0100)
committerIngo Molnar <mingo@kernel.org>
Tue, 7 Feb 2017 07:49:17 +0000 (08:49 +0100)
Signed-off-by: Ingo Molnar <mingo@kernel.org>
17 files changed:
arch/x86/boot/compressed/eboot.c
arch/x86/kernel/acpi/boot.c
arch/x86/platform/efi/efi-bgrt.c
arch/x86/platform/efi/efi.c
arch/x86/platform/efi/efi_64.c
drivers/acpi/bgrt.c
drivers/firmware/efi/arm-init.c
drivers/firmware/efi/efi.c
drivers/firmware/efi/esrt.c
drivers/firmware/efi/libstub/Makefile
drivers/firmware/efi/libstub/arm-stub.c
drivers/firmware/efi/libstub/efi-stub-helper.c
drivers/firmware/efi/libstub/efistub.h
drivers/firmware/efi/memattr.c
include/linux/efi-bgrt.h
include/linux/efi.h
init/main.c

index ff01c8fc76f74223c9254f0aae1317de16834ced..6d3aeabbce68b75c2a7db3dae8ba7bcf8853eee3 100644 (file)
@@ -38,154 +38,6 @@ static void setup_boot_services##bits(struct efi_config *c)         \
 BOOT_SERVICES(32);
 BOOT_SERVICES(64);
 
-void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
-
-static efi_status_t
-__file_size32(void *__fh, efi_char16_t *filename_16,
-             void **handle, u64 *file_sz)
-{
-       efi_file_handle_32_t *h, *fh = __fh;
-       efi_file_info_t *info;
-       efi_status_t status;
-       efi_guid_t info_guid = EFI_FILE_INFO_ID;
-       u32 info_sz;
-
-       status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16,
-                                EFI_FILE_MODE_READ, (u64)0);
-       if (status != EFI_SUCCESS) {
-               efi_printk(sys_table, "Failed to open file: ");
-               efi_char16_printk(sys_table, filename_16);
-               efi_printk(sys_table, "\n");
-               return status;
-       }
-
-       *handle = h;
-
-       info_sz = 0;
-       status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
-                                &info_sz, NULL);
-       if (status != EFI_BUFFER_TOO_SMALL) {
-               efi_printk(sys_table, "Failed to get file info size\n");
-               return status;
-       }
-
-grow:
-       status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
-                               info_sz, (void **)&info);
-       if (status != EFI_SUCCESS) {
-               efi_printk(sys_table, "Failed to alloc mem for file info\n");
-               return status;
-       }
-
-       status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
-                                &info_sz, info);
-       if (status == EFI_BUFFER_TOO_SMALL) {
-               efi_call_early(free_pool, info);
-               goto grow;
-       }
-
-       *file_sz = info->file_size;
-       efi_call_early(free_pool, info);
-
-       if (status != EFI_SUCCESS)
-               efi_printk(sys_table, "Failed to get initrd info\n");
-
-       return status;
-}
-
-static efi_status_t
-__file_size64(void *__fh, efi_char16_t *filename_16,
-             void **handle, u64 *file_sz)
-{
-       efi_file_handle_64_t *h, *fh = __fh;
-       efi_file_info_t *info;
-       efi_status_t status;
-       efi_guid_t info_guid = EFI_FILE_INFO_ID;
-       u64 info_sz;
-
-       status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16,
-                                EFI_FILE_MODE_READ, (u64)0);
-       if (status != EFI_SUCCESS) {
-               efi_printk(sys_table, "Failed to open file: ");
-               efi_char16_printk(sys_table, filename_16);
-               efi_printk(sys_table, "\n");
-               return status;
-       }
-
-       *handle = h;
-
-       info_sz = 0;
-       status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
-                                &info_sz, NULL);
-       if (status != EFI_BUFFER_TOO_SMALL) {
-               efi_printk(sys_table, "Failed to get file info size\n");
-               return status;
-       }
-
-grow:
-       status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
-                               info_sz, (void **)&info);
-       if (status != EFI_SUCCESS) {
-               efi_printk(sys_table, "Failed to alloc mem for file info\n");
-               return status;
-       }
-
-       status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
-                                &info_sz, info);
-       if (status == EFI_BUFFER_TOO_SMALL) {
-               efi_call_early(free_pool, info);
-               goto grow;
-       }
-
-       *file_sz = info->file_size;
-       efi_call_early(free_pool, info);
-
-       if (status != EFI_SUCCESS)
-               efi_printk(sys_table, "Failed to get initrd info\n");
-
-       return status;
-}
-efi_status_t
-efi_file_size(efi_system_table_t *sys_table, void *__fh,
-             efi_char16_t *filename_16, void **handle, u64 *file_sz)
-{
-       if (efi_early->is64)
-               return __file_size64(__fh, filename_16, handle, file_sz);
-
-       return __file_size32(__fh, filename_16, handle, file_sz);
-}
-
-efi_status_t
-efi_file_read(void *handle, unsigned long *size, void *addr)
-{
-       unsigned long func;
-
-       if (efi_early->is64) {
-               efi_file_handle_64_t *fh = handle;
-
-               func = (unsigned long)fh->read;
-               return efi_early->call(func, handle, size, addr);
-       } else {
-               efi_file_handle_32_t *fh = handle;
-
-               func = (unsigned long)fh->read;
-               return efi_early->call(func, handle, size, addr);
-       }
-}
-
-efi_status_t efi_file_close(void *handle)
-{
-       if (efi_early->is64) {
-               efi_file_handle_64_t *fh = handle;
-
-               return efi_early->call((unsigned long)fh->close, handle);
-       } else {
-               efi_file_handle_32_t *fh = handle;
-
-               return efi_early->call((unsigned long)fh->close, handle);
-       }
-}
-
 static inline efi_status_t __open_volume32(void *__image, void **__fh)
 {
        efi_file_io_interface_t *io;
@@ -249,30 +101,8 @@ efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh)
 
 void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str)
 {
-       unsigned long output_string;
-       size_t offset;
-
-       if (efi_early->is64) {
-               struct efi_simple_text_output_protocol_64 *out;
-               u64 *func;
-
-               offset = offsetof(typeof(*out), output_string);
-               output_string = efi_early->text_output + offset;
-               out = (typeof(out))(unsigned long)efi_early->text_output;
-               func = (u64 *)output_string;
-
-               efi_early->call(*func, out, str);
-       } else {
-               struct efi_simple_text_output_protocol_32 *out;
-               u32 *func;
-
-               offset = offsetof(typeof(*out), output_string);
-               output_string = efi_early->text_output + offset;
-               out = (typeof(out))(unsigned long)efi_early->text_output;
-               func = (u32 *)output_string;
-
-               efi_early->call(*func, out, str);
-       }
+       efi_call_proto(efi_simple_text_output_protocol, output_string,
+                      efi_early->text_output, str);
 }
 
 static efi_status_t
index 64422f850e95e2da7991ded073041f5df5b4dfae..7ff007ed899d1731c97eba25fc40ccac38a90309 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/bootmem.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
+#include <linux/efi-bgrt.h>
 
 #include <asm/irqdomain.h>
 #include <asm/pci_x86.h>
@@ -1557,6 +1558,12 @@ int __init early_acpi_boot_init(void)
        return 0;
 }
 
+static int __init acpi_parse_bgrt(struct acpi_table_header *table)
+{
+       efi_bgrt_init(table);
+       return 0;
+}
+
 int __init acpi_boot_init(void)
 {
        /* those are executed after early-quirks are executed */
@@ -1581,6 +1588,8 @@ int __init acpi_boot_init(void)
        acpi_process_madt();
 
        acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet);
+       if (IS_ENABLED(CONFIG_ACPI_BGRT))
+               acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
 
        if (!acpi_noirq)
                x86_init.pci.init = pci_acpi_init;
index 6aad870e89620974a685c40300f77cb7694a6f93..04ca8764f0c096f4e3f006ab74e4dc55996735a1 100644 (file)
@@ -19,8 +19,7 @@
 #include <linux/efi.h>
 #include <linux/efi-bgrt.h>
 
-struct acpi_table_bgrt *bgrt_tab;
-void *__initdata bgrt_image;
+struct acpi_table_bgrt bgrt_tab;
 size_t __initdata bgrt_image_size;
 
 struct bmp_header {
@@ -28,66 +27,58 @@ struct bmp_header {
        u32 size;
 } __packed;
 
-void __init efi_bgrt_init(void)
+void __init efi_bgrt_init(struct acpi_table_header *table)
 {
-       acpi_status status;
        void *image;
        struct bmp_header bmp_header;
+       struct acpi_table_bgrt *bgrt = &bgrt_tab;
 
        if (acpi_disabled)
                return;
 
-       status = acpi_get_table("BGRT", 0,
-                               (struct acpi_table_header **)&bgrt_tab);
-       if (ACPI_FAILURE(status))
-               return;
-
-       if (bgrt_tab->header.length < sizeof(*bgrt_tab)) {
+       if (table->length < sizeof(bgrt_tab)) {
                pr_notice("Ignoring BGRT: invalid length %u (expected %zu)\n",
-                      bgrt_tab->header.length, sizeof(*bgrt_tab));
+                      table->length, sizeof(bgrt_tab));
                return;
        }
-       if (bgrt_tab->version != 1) {
+       *bgrt = *(struct acpi_table_bgrt *)table;
+       if (bgrt->version != 1) {
                pr_notice("Ignoring BGRT: invalid version %u (expected 1)\n",
-                      bgrt_tab->version);
-               return;
+                      bgrt->version);
+               goto out;
        }
-       if (bgrt_tab->status & 0xfe) {
+       if (bgrt->status & 0xfe) {
                pr_notice("Ignoring BGRT: reserved status bits are non-zero %u\n",
-                      bgrt_tab->status);
-               return;
+                      bgrt->status);
+               goto out;
        }
-       if (bgrt_tab->image_type != 0) {
+       if (bgrt->image_type != 0) {
                pr_notice("Ignoring BGRT: invalid image type %u (expected 0)\n",
-                      bgrt_tab->image_type);
-               return;
+                      bgrt->image_type);
+               goto out;
        }
-       if (!bgrt_tab->image_address) {
+       if (!bgrt->image_address) {
                pr_notice("Ignoring BGRT: null image address\n");
-               return;
+               goto out;
        }
 
-       image = memremap(bgrt_tab->image_address, sizeof(bmp_header), MEMREMAP_WB);
+       image = early_memremap(bgrt->image_address, sizeof(bmp_header));
        if (!image) {
                pr_notice("Ignoring BGRT: failed to map image header memory\n");
-               return;
+               goto out;
        }
 
        memcpy(&bmp_header, image, sizeof(bmp_header));
-       memunmap(image);
+       early_memunmap(image, sizeof(bmp_header));
        if (bmp_header.id != 0x4d42) {
                pr_notice("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n",
                        bmp_header.id);
-               return;
+               goto out;
        }
        bgrt_image_size = bmp_header.size;
+       efi_mem_reserve(bgrt->image_address, bgrt_image_size);
 
-       bgrt_image = memremap(bgrt_tab->image_address, bmp_header.size, MEMREMAP_WB);
-       if (!bgrt_image) {
-               pr_notice("Ignoring BGRT: failed to map image memory\n");
-               bgrt_image = NULL;
-               return;
-       }
-
-       efi_mem_reserve(bgrt_tab->image_address, bgrt_image_size);
+       return;
+out:
+       memset(bgrt, 0, sizeof(bgrt_tab));
 }
index 274dfc48184977db435a9c5c78607cd8a182067c..565dff3c9a12cf1f042fae494d1bdb3a55d032b3 100644 (file)
@@ -542,11 +542,6 @@ void __init efi_init(void)
                efi_print_memmap();
 }
 
-void __init efi_late_init(void)
-{
-       efi_bgrt_init();
-}
-
 void __init efi_set_executable(efi_memory_desc_t *md, bool executable)
 {
        u64 addr, npages;
@@ -960,6 +955,11 @@ static void __init __efi_enter_virtual_mode(void)
                return;
        }
 
+       if (efi_enabled(EFI_DBG)) {
+               pr_info("EFI runtime memory map:\n");
+               efi_print_memmap();
+       }
+
        BUG_ON(!efi.systab);
 
        if (efi_setup_page_tables(pa, 1 << pg_shift)) {
index 2f25a363068cf9723e8b418e8c1942a6d3ca4029..a4695da42d77b39cec3b65083c7b7115b1faa32d 100644 (file)
@@ -414,10 +414,44 @@ void __init parse_efi_setup(u64 phys_addr, u32 data_len)
        efi_setup = phys_addr + sizeof(struct setup_data);
 }
 
-void __init efi_runtime_update_mappings(void)
+static int __init efi_update_mappings(efi_memory_desc_t *md, unsigned long pf)
 {
        unsigned long pfn;
        pgd_t *pgd = efi_pgd;
+       int err1, err2;
+
+       /* Update the 1:1 mapping */
+       pfn = md->phys_addr >> PAGE_SHIFT;
+       err1 = kernel_map_pages_in_pgd(pgd, pfn, md->phys_addr, md->num_pages, pf);
+       if (err1) {
+               pr_err("Error while updating 1:1 mapping PA 0x%llx -> VA 0x%llx!\n",
+                          md->phys_addr, md->virt_addr);
+       }
+
+       err2 = kernel_map_pages_in_pgd(pgd, pfn, md->virt_addr, md->num_pages, pf);
+       if (err2) {
+               pr_err("Error while updating VA mapping PA 0x%llx -> VA 0x%llx!\n",
+                          md->phys_addr, md->virt_addr);
+       }
+
+       return err1 || err2;
+}
+
+static int __init efi_update_mem_attr(struct mm_struct *mm, efi_memory_desc_t *md)
+{
+       unsigned long pf = 0;
+
+       if (md->attribute & EFI_MEMORY_XP)
+               pf |= _PAGE_NX;
+
+       if (!(md->attribute & EFI_MEMORY_RO))
+               pf |= _PAGE_RW;
+
+       return efi_update_mappings(md, pf);
+}
+
+void __init efi_runtime_update_mappings(void)
+{
        efi_memory_desc_t *md;
 
        if (efi_enabled(EFI_OLD_MEMMAP)) {
@@ -426,6 +460,24 @@ void __init efi_runtime_update_mappings(void)
                return;
        }
 
+       /*
+        * Use the EFI Memory Attribute Table for mapping permissions if it
+        * exists, since it is intended to supersede EFI_PROPERTIES_TABLE.
+        */
+       if (efi_enabled(EFI_MEM_ATTR)) {
+               efi_memattr_apply_permissions(NULL, efi_update_mem_attr);
+               return;
+       }
+
+       /*
+        * EFI_MEMORY_ATTRIBUTES_TABLE is intended to replace
+        * EFI_PROPERTIES_TABLE. So, use EFI_PROPERTIES_TABLE to update
+        * permissions only if EFI_MEMORY_ATTRIBUTES_TABLE is not
+        * published by the firmware. Even if we find a buggy implementation of
+        * EFI_MEMORY_ATTRIBUTES_TABLE, don't fall back to
+        * EFI_PROPERTIES_TABLE, because of the same reason.
+        */
+
        if (!efi_enabled(EFI_NX_PE_DATA))
                return;
 
@@ -446,15 +498,7 @@ void __init efi_runtime_update_mappings(void)
                        (md->type != EFI_RUNTIME_SERVICES_CODE))
                        pf |= _PAGE_RW;
 
-               /* Update the 1:1 mapping */
-               pfn = md->phys_addr >> PAGE_SHIFT;
-               if (kernel_map_pages_in_pgd(pgd, pfn, md->phys_addr, md->num_pages, pf))
-                       pr_warn("Error mapping PA 0x%llx -> VA 0x%llx!\n",
-                                  md->phys_addr, md->virt_addr);
-
-               if (kernel_map_pages_in_pgd(pgd, pfn, md->virt_addr, md->num_pages, pf))
-                       pr_warn("Error mapping PA 0x%llx -> VA 0x%llx!\n",
-                                  md->phys_addr, md->virt_addr);
+               efi_update_mappings(md, pf);
        }
 }
 
index 75f128e766a979e38a3a91ca00ec8fbde5b686dc..ca28aa572aa9543f5fc148221fc5b902c6fdfd02 100644 (file)
 #include <linux/sysfs.h>
 #include <linux/efi-bgrt.h>
 
+static void *bgrt_image;
 static struct kobject *bgrt_kobj;
 
 static ssize_t show_version(struct device *dev,
                            struct device_attribute *attr, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->version);
+       return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.version);
 }
 static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
 
 static ssize_t show_status(struct device *dev,
                           struct device_attribute *attr, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->status);
+       return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.status);
 }
 static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
 
 static ssize_t show_type(struct device *dev,
                         struct device_attribute *attr, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_type);
+       return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_type);
 }
 static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
 
 static ssize_t show_xoffset(struct device *dev,
                            struct device_attribute *attr, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_x);
+       return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_x);
 }
 static DEVICE_ATTR(xoffset, S_IRUGO, show_xoffset, NULL);
 
 static ssize_t show_yoffset(struct device *dev,
                            struct device_attribute *attr, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_y);
+       return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_y);
 }
 static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL);
 
@@ -84,15 +85,24 @@ static int __init bgrt_init(void)
 {
        int ret;
 
-       if (!bgrt_image)
+       if (!bgrt_tab.image_address)
                return -ENODEV;
 
+       bgrt_image = memremap(bgrt_tab.image_address, bgrt_image_size,
+                             MEMREMAP_WB);
+       if (!bgrt_image) {
+               pr_notice("Ignoring BGRT: failed to map image memory\n");
+               return -ENOMEM;
+       }
+
        bin_attr_image.private = bgrt_image;
        bin_attr_image.size = bgrt_image_size;
 
        bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj);
-       if (!bgrt_kobj)
-               return -EINVAL;
+       if (!bgrt_kobj) {
+               ret = -EINVAL;
+               goto out_memmap;
+       }
 
        ret = sysfs_create_group(bgrt_kobj, &bgrt_attribute_group);
        if (ret)
@@ -102,6 +112,8 @@ static int __init bgrt_init(void)
 
 out_kobject:
        kobject_put(bgrt_kobj);
+out_memmap:
+       memunmap(bgrt_image);
        return ret;
 }
 device_initcall(bgrt_init);
index f853ad2c4ca0a7d42d888cbd95844d6b132eb925..1027d7b44358d3b5806e8dcd58c65fecdcab9664 100644 (file)
@@ -250,7 +250,6 @@ void __init efi_init(void)
        }
 
        reserve_regions();
-       efi_memattr_init();
        efi_esrt_init();
        efi_memmap_unmap();
 
index 92914801e3888775708a2c3843f5a6577529d9d0..e7d404059b7316a5c5668f609ceb5957fdcdd97d 100644 (file)
@@ -529,6 +529,8 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
                }
        }
 
+       efi_memattr_init();
+
        /* Parse the EFI Properties table if it exists */
        if (efi.properties_table != EFI_INVALID_TABLE_ADDR) {
                efi_properties_table_t *tbl;
index 14914074f716ed41cc3fccc42c1e333810ecf890..08b026864d4e7d5f00b76cbd95b7398c6db943f8 100644 (file)
@@ -269,7 +269,7 @@ void __init efi_esrt_init(void)
        max -= efi.esrt;
 
        if (max < size) {
-               pr_err("ESRT header doen't fit on single memory map entry. (size: %zu max: %zu)\n",
+               pr_err("ESRT header doesn't fit on single memory map entry. (size: %zu max: %zu)\n",
                       size, max);
                return;
        }
index d564d25df8abf14c8b00cafe861fed063e09af4b..33e0e2f1a730109989c61994bbcd93560e542f03 100644 (file)
@@ -11,7 +11,7 @@ cflags-$(CONFIG_X86)          += -m$(BITS) -D__KERNEL__ -O2 \
                                   -mno-mmx -mno-sse
 
 cflags-$(CONFIG_ARM64)         := $(subst -pg,,$(KBUILD_CFLAGS))
-cflags-$(CONFIG_ARM)           := $(subst -pg,,$(KBUILD_CFLAGS)) -g0 \
+cflags-$(CONFIG_ARM)           := $(subst -pg,,$(KBUILD_CFLAGS)) \
                                   -fno-builtin -fpic -mno-single-pic-base
 
 cflags-$(CONFIG_EFI_ARMSTUB)   += -I$(srctree)/scripts/dtc/libfdt
@@ -60,7 +60,7 @@ CFLAGS_arm64-stub.o           := -DTEXT_OFFSET=$(TEXT_OFFSET)
 extra-$(CONFIG_EFI_ARMSTUB)    := $(lib-y)
 lib-$(CONFIG_EFI_ARMSTUB)      := $(patsubst %.o,%.stub.o,$(lib-y))
 
-STUBCOPY_FLAGS-y               := -R .debug* -R *ksymtab* -R *kcrctab*
+STUBCOPY_RM-y                  := -R *ksymtab* -R *kcrctab*
 STUBCOPY_FLAGS-$(CONFIG_ARM64) += --prefix-alloc-sections=.init \
                                   --prefix-symbols=__efistub_
 STUBCOPY_RELOC-$(CONFIG_ARM64) := R_AARCH64_ABS
@@ -68,17 +68,25 @@ STUBCOPY_RELOC-$(CONFIG_ARM64)      := R_AARCH64_ABS
 $(obj)/%.stub.o: $(obj)/%.o FORCE
        $(call if_changed,stubcopy)
 
+#
+# Strip debug sections and some other sections that may legally contain
+# absolute relocations, so that we can inspect the remaining sections for
+# such relocations. If none are found, regenerate the output object, but
+# this time, use objcopy and leave all sections in place.
+#
 quiet_cmd_stubcopy = STUBCPY $@
-      cmd_stubcopy = if $(OBJCOPY) $(STUBCOPY_FLAGS-y) $< $@; then     \
-                    $(OBJDUMP) -r $@ | grep $(STUBCOPY_RELOC-y)        \
-                    && (echo >&2 "$@: absolute symbol references not allowed in the EFI stub"; \
-                        rm -f $@; /bin/false); else /bin/false; fi
+      cmd_stubcopy = if $(STRIP) --strip-debug $(STUBCOPY_RM-y) -o $@ $<; \
+                    then if $(OBJDUMP) -r $@ | grep $(STUBCOPY_RELOC-y); \
+                    then (echo >&2 "$@: absolute symbol references not allowed in the EFI stub"; \
+                          rm -f $@; /bin/false);                         \
+                    else $(OBJCOPY) $(STUBCOPY_FLAGS-y) $< $@; fi        \
+                    else /bin/false; fi
 
 #
 # ARM discards the .data section because it disallows r/w data in the
 # decompressor. So move our .data to .data.efistub, which is preserved
 # explicitly by the decompressor linker script.
 #
-STUBCOPY_FLAGS-$(CONFIG_ARM)   += --rename-section .data=.data.efistub \
-                                  -R ___ksymtab+sort -R ___kcrctab+sort
+STUBCOPY_FLAGS-$(CONFIG_ARM)   += --rename-section .data=.data.efistub
+STUBCOPY_RM-$(CONFIG_ARM)      += -R ___ksymtab+sort -R ___kcrctab+sort
 STUBCOPY_RELOC-$(CONFIG_ARM)   := R_ARM_ABS
index b4f7d78f9e8bdeafb4e7bb408f3648aa9cacd45d..6fca48c9e054b8c82e9b60e188ed6a460a290613 100644 (file)
@@ -91,75 +91,6 @@ efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
        return status;
 }
 
-efi_status_t efi_file_close(void *handle)
-{
-       efi_file_handle_t *fh = handle;
-
-       return fh->close(handle);
-}
-
-efi_status_t
-efi_file_read(void *handle, unsigned long *size, void *addr)
-{
-       efi_file_handle_t *fh = handle;
-
-       return fh->read(handle, size, addr);
-}
-
-
-efi_status_t
-efi_file_size(efi_system_table_t *sys_table_arg, void *__fh,
-             efi_char16_t *filename_16, void **handle, u64 *file_sz)
-{
-       efi_file_handle_t *h, *fh = __fh;
-       efi_file_info_t *info;
-       efi_status_t status;
-       efi_guid_t info_guid = EFI_FILE_INFO_ID;
-       unsigned long info_sz;
-
-       status = fh->open(fh, &h, filename_16, EFI_FILE_MODE_READ, (u64)0);
-       if (status != EFI_SUCCESS) {
-               efi_printk(sys_table_arg, "Failed to open file: ");
-               efi_char16_printk(sys_table_arg, filename_16);
-               efi_printk(sys_table_arg, "\n");
-               return status;
-       }
-
-       *handle = h;
-
-       info_sz = 0;
-       status = h->get_info(h, &info_guid, &info_sz, NULL);
-       if (status != EFI_BUFFER_TOO_SMALL) {
-               efi_printk(sys_table_arg, "Failed to get file info size\n");
-               return status;
-       }
-
-grow:
-       status = sys_table_arg->boottime->allocate_pool(EFI_LOADER_DATA,
-                                info_sz, (void **)&info);
-       if (status != EFI_SUCCESS) {
-               efi_printk(sys_table_arg, "Failed to alloc mem for file info\n");
-               return status;
-       }
-
-       status = h->get_info(h, &info_guid, &info_sz,
-                                                  info);
-       if (status == EFI_BUFFER_TOO_SMALL) {
-               sys_table_arg->boottime->free_pool(info);
-               goto grow;
-       }
-
-       *file_sz = info->file_size;
-       sys_table_arg->boottime->free_pool(info);
-
-       if (status != EFI_SUCCESS)
-               efi_printk(sys_table_arg, "Failed to get initrd info\n");
-
-       return status;
-}
-
-
-
 void efi_char16_printk(efi_system_table_t *sys_table_arg,
                              efi_char16_t *str)
 {
index 757badc1debbedbec5ecaa64c724c85b3b2e7632..6ee9164251a94cf46ac64f4fac503ba4840886e2 100644 (file)
@@ -338,6 +338,69 @@ void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
        efi_call_early(free_pages, addr, nr_pages);
 }
 
+static efi_status_t efi_file_size(efi_system_table_t *sys_table_arg, void *__fh,
+                                 efi_char16_t *filename_16, void **handle,
+                                 u64 *file_sz)
+{
+       efi_file_handle_t *h, *fh = __fh;
+       efi_file_info_t *info;
+       efi_status_t status;
+       efi_guid_t info_guid = EFI_FILE_INFO_ID;
+       unsigned long info_sz;
+
+       status = efi_call_proto(efi_file_handle, open, fh, &h, filename_16,
+                               EFI_FILE_MODE_READ, (u64)0);
+       if (status != EFI_SUCCESS) {
+               efi_printk(sys_table_arg, "Failed to open file: ");
+               efi_char16_printk(sys_table_arg, filename_16);
+               efi_printk(sys_table_arg, "\n");
+               return status;
+       }
+
+       *handle = h;
+
+       info_sz = 0;
+       status = efi_call_proto(efi_file_handle, get_info, h, &info_guid,
+                               &info_sz, NULL);
+       if (status != EFI_BUFFER_TOO_SMALL) {
+               efi_printk(sys_table_arg, "Failed to get file info size\n");
+               return status;
+       }
+
+grow:
+       status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+                               info_sz, (void **)&info);
+       if (status != EFI_SUCCESS) {
+               efi_printk(sys_table_arg, "Failed to alloc mem for file info\n");
+               return status;
+       }
+
+       status = efi_call_proto(efi_file_handle, get_info, h, &info_guid,
+                               &info_sz, info);
+       if (status == EFI_BUFFER_TOO_SMALL) {
+               efi_call_early(free_pool, info);
+               goto grow;
+       }
+
+       *file_sz = info->file_size;
+       efi_call_early(free_pool, info);
+
+       if (status != EFI_SUCCESS)
+               efi_printk(sys_table_arg, "Failed to get initrd info\n");
+
+       return status;
+}
+
+static efi_status_t efi_file_read(void *handle, unsigned long *size, void *addr)
+{
+       return efi_call_proto(efi_file_handle, read, handle, size, addr);
+}
+
+static efi_status_t efi_file_close(void *handle)
+{
+       return efi_call_proto(efi_file_handle, close, handle);
+}
+
 /*
  * Parse the ASCII string 'cmdline' for EFI options, denoted by the efi=
  * option, e.g. efi=nochunk.
index 0e2a96b12cb3647635db19912ec0ab4004f71572..71c4d0e3c4ede196cffeebec1ccef97e868b3f26 100644 (file)
@@ -29,14 +29,6 @@ void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
 efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg, void *__image,
                             void **__fh);
 
-efi_status_t efi_file_size(efi_system_table_t *sys_table_arg, void *__fh,
-                          efi_char16_t *filename_16, void **handle,
-                          u64 *file_sz);
-
-efi_status_t efi_file_read(void *handle, unsigned long *size, void *addr);
-
-efi_status_t efi_file_close(void *handle);
-
 unsigned long get_dram_base(efi_system_table_t *sys_table_arg);
 
 efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
index 236004b9a50d3224024d0024b8774b6347995065..8986757eafafa29dbf287b9e45b4de592cbc9570 100644 (file)
@@ -43,6 +43,7 @@ int __init efi_memattr_init(void)
 
        tbl_size = sizeof(*tbl) + tbl->num_entries * tbl->desc_size;
        memblock_reserve(efi.mem_attr_table, tbl_size);
+       set_bit(EFI_MEM_ATTR, &efi.flags);
 
 unmap:
        early_memunmap(tbl, sizeof(*tbl));
@@ -174,8 +175,11 @@ int __init efi_memattr_apply_permissions(struct mm_struct *mm,
                                md.phys_addr + size - 1,
                                efi_md_typeattr_format(buf, sizeof(buf), &md));
 
-               if (valid)
+               if (valid) {
                        ret = fn(mm, &md);
+                       if (ret)
+                               pr_err("Error updating mappings, skipping subsequent md's\n");
+               }
        }
        memunmap(tbl);
        return ret;
index 051b21fedf681a39d102da1a16ddb2a33e0ff0f4..2fd3993c370b273c9ae8c0f58604a1280527f832 100644 (file)
@@ -1,20 +1,19 @@
 #ifndef _LINUX_EFI_BGRT_H
 #define _LINUX_EFI_BGRT_H
 
-#ifdef CONFIG_ACPI_BGRT
-
 #include <linux/acpi.h>
 
-void efi_bgrt_init(void);
+#ifdef CONFIG_ACPI_BGRT
+
+void efi_bgrt_init(struct acpi_table_header *table);
 
 /* The BGRT data itself; only valid if bgrt_image != NULL. */
-extern void *bgrt_image;
 extern size_t bgrt_image_size;
-extern struct acpi_table_bgrt *bgrt_tab;
+extern struct acpi_table_bgrt bgrt_tab;
 
 #else /* !CONFIG_ACPI_BGRT */
 
-static inline void efi_bgrt_init(void) {}
+static inline void efi_bgrt_init(struct acpi_table_header *table) {}
 
 #endif /* !CONFIG_ACPI_BGRT */
 
index 5b1af30ece55828e655b2bf02a149fd71354f3eb..85e9fdaa8d0720d4f51b765e8f939e421e3edc90 100644 (file)
@@ -509,24 +509,6 @@ typedef struct {
        u64 query_variable_info;
 } efi_runtime_services_64_t;
 
-typedef struct {
-       efi_table_hdr_t hdr;
-       void *get_time;
-       void *set_time;
-       void *get_wakeup_time;
-       void *set_wakeup_time;
-       void *set_virtual_address_map;
-       void *convert_pointer;
-       void *get_variable;
-       void *get_next_variable;
-       void *set_variable;
-       void *get_next_high_mono_count;
-       void *reset_system;
-       void *update_capsule;
-       void *query_capsule_caps;
-       void *query_variable_info;
-} efi_runtime_services_t;
-
 typedef efi_status_t efi_get_time_t (efi_time_t *tm, efi_time_cap_t *tc);
 typedef efi_status_t efi_set_time_t (efi_time_t *tm);
 typedef efi_status_t efi_get_wakeup_time_t (efi_bool_t *enabled, efi_bool_t *pending,
@@ -561,6 +543,24 @@ typedef efi_status_t efi_query_variable_store_t(u32 attributes,
                                                unsigned long size,
                                                bool nonblocking);
 
+typedef struct {
+       efi_table_hdr_t                 hdr;
+       efi_get_time_t                  *get_time;
+       efi_set_time_t                  *set_time;
+       efi_get_wakeup_time_t           *get_wakeup_time;
+       efi_set_wakeup_time_t           *set_wakeup_time;
+       efi_set_virtual_address_map_t   *set_virtual_address_map;
+       void                            *convert_pointer;
+       efi_get_variable_t              *get_variable;
+       efi_get_next_variable_t         *get_next_variable;
+       efi_set_variable_t              *set_variable;
+       efi_get_next_high_mono_count_t  *get_next_high_mono_count;
+       efi_reset_system_t              *reset_system;
+       efi_update_capsule_t            *update_capsule;
+       efi_query_capsule_caps_t        *query_capsule_caps;
+       efi_query_variable_info_t       *query_variable_info;
+} efi_runtime_services_t;
+
 void efi_native_runtime_setup(void);
 
 /*
@@ -1065,6 +1065,7 @@ extern int __init efi_setup_pcdp_console(char *);
 #define EFI_ARCH_1             7       /* First arch-specific bit */
 #define EFI_DBG                        8       /* Print additional debug info at runtime */
 #define EFI_NX_PE_DATA         9       /* Can runtime data regions be mapped non-executable? */
+#define EFI_MEM_ATTR           10      /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */
 
 #ifdef CONFIG_EFI
 /*
@@ -1240,17 +1241,17 @@ struct efivar_entry {
        bool deleting;
 };
 
-struct efi_simple_text_output_protocol_32 {
+typedef struct {
        u32 reset;
        u32 output_string;
        u32 test_string;
-};
+} efi_simple_text_output_protocol_32_t;
 
-struct efi_simple_text_output_protocol_64 {
+typedef struct {
        u64 reset;
        u64 output_string;
        u64 test_string;
-};
+} efi_simple_text_output_protocol_64_t;
 
 struct efi_simple_text_output_protocol {
        void *reset;
index b0c9d6facef9a5aced55d1443b40029a660011e8..9648d707eea58c14f16d27543ca942006fa33d32 100644 (file)
@@ -663,7 +663,6 @@ asmlinkage __visible void __init start_kernel(void)
        sfi_init_late();
 
        if (efi_enabled(EFI_RUNTIME_SERVICES)) {
-               efi_late_init();
                efi_free_boot_services();
        }