EFI changes for v4.11
Subsystems (6)
Linus,
Please pull the latest efi-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git efi-core-for-linus
# HEAD: b3879a4d3a31ef14265a52e8d941cf4b0f6627ae efi/libstub: Make file I/O chunking x86-specific
The main changes in this cycle were:
- Changes to the EFI init code to establish whether secure boot authentication was performed at boot time. (Josh Boyer, David Howells)
- Wire up the UEFI memory attributes table for x86. This eliminates any runtime memory regions that are both writable and executable, on recent firmware versions. (Sai Praneeth)
- Move the BGRT init code to an earlier stage so that we can still use efi_mem_reserve(). (Dave Young)
- Preserve debug symbols in the ARM/arm64 UEFI stub (Ard Biesheuvel)
- Code deduplication work and various other cleanups (Lukas Wunner)
- ... plus various other fixes and cleanups.
Thanks,
Ingo
------------------>
Ard Biesheuvel (3):
efi: Use typed function pointers for the runtime services table efi/libstub: Preserve .debug sections after absolute relocation check efi/libstub: Make file I/O chunking x86-specific
Colin Ian King (1):
efi/esrt: Fix typo in pr_err() message
Dave Young (2):
efi/x86: Move the EFI BGRT init code to early init code efi/x86: Add debug code to print cooked memmap
David Howells (4):
x86/efi: Allow invocation of arbitrary runtime services arm/efi: Allow invocation of arbitrary runtime services
efi: Get and store the secure boot status
efi: Print the secure boot status in x86 setup_arch()
Josh Boyer (2):
efi: Add SHIM and image security database GUID definitions
efi: Disable secure boot if shim is in insecure mode
Lukas Wunner (2):
efi: Deduplicate efi_file_size() / _read() / _close() x86/efi: Deduplicate efi_char16_printk()
Sai Praneeth (3):
efi: Make EFI_MEMORY_ATTRIBUTES_TABLE initialization common across all architectures
efi: Introduce the EFI_MEM_ATTR bit and set it from the memory attributes table x86/efi: Add support for EFI_MEMORY_ATTRIBUTES_TABLE
Documentation/x86/zero-page.txt | 2 + arch/arm/include/asm/efi.h | 1 + arch/arm64/include/asm/efi.h | 1 + arch/x86/boot/compressed/eboot.c | 182 ++----------------------- arch/x86/boot/compressed/head_32.S | 6 +- arch/x86/boot/compressed/head_64.S | 8 +- arch/x86/include/asm/efi.h | 5 + arch/x86/include/uapi/asm/bootparam.h | 3 +- arch/x86/kernel/acpi/boot.c | 9 ++ arch/x86/kernel/asm-offsets.c | 1 + arch/x86/kernel/setup.c | 14 ++ arch/x86/platform/efi/efi-bgrt.c | 59 ++++---- arch/x86/platform/efi/efi.c | 10 +- arch/x86/platform/efi/efi_64.c | 64 +++++++-- drivers/acpi/bgrt.c | 28 ++-- drivers/firmware/efi/arm-init.c | 1 - drivers/firmware/efi/efi.c | 2 + drivers/firmware/efi/esrt.c | 2 +- drivers/firmware/efi/libstub/Makefile | 26 ++-- drivers/firmware/efi/libstub/arm-stub.c | 132 +----------------- drivers/firmware/efi/libstub/efi-stub-helper.c | 74 +++++++++- drivers/firmware/efi/libstub/efistub.h | 8 -- drivers/firmware/efi/libstub/secureboot.c | 84 ++++++++++++ drivers/firmware/efi/memattr.c | 6 +- include/linux/efi-bgrt.h | 11 +- include/linux/efi.h | 56 +++++--- init/main.c | 1 - 27 files changed, 383 insertions(+), 413 deletions(-) create mode 100644 drivers/firmware/efi/libstub/secureboot.c
Documentation/x86/zero-page.txt +2 -0
@@ -31,6 +31,8 @@ Offset Proto Name Meaning 1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below) 1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer (below) +1EB/001 ALL kbd_status Numlock is enabled +1EC/001 ALL secure_boot Secure boot is enabled in the firmware 1EF/001 ALL sentinel Used to detect broken bootloaders 290/040 ALL edd_mbr_sig_buffer EDD MBR signatures 2D0/A00 ALL e820_map E820 memory map table
arch/arm/include/asm/efi.h +1 -0
@@ -55,6 +55,7 @@ void efi_virtmap_unload(void);#define efi_call_early (f, ...) sys_table_arg->boottime->f(__VA_ARGS__)#define __efi_call_early (f, ...) f(__VA_ARGS__) +#define efi_call_runtime (f, ...) sys_table_arg->runtime->f(__VA_ARGS__)#define efi_is_64bit () (false)#define efi_call_proto (protocol, f, instance, ...) \
arch/arm64/include/asm/efi.h +1 -0
@@ -50,6 +50,7 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);#define efi_call_early (f, ...) sys_table_arg->boottime->f(__VA_ARGS__)#define __efi_call_early (f, ...) f(__VA_ARGS__) +#define efi_call_runtime (f, ...) sys_table_arg->runtime->f(__VA_ARGS__)#define efi_is_64bit () (true)#define efi_call_proto (protocol, f, instance, ...) \
arch/x86/boot/compressed/eboot.c +10 -172
206 lines not on this page · raw message
arch/x86/boot/compressed/head_32.S +3 -3
@@ -82,7 +82,7 @@ ENTRY(efi_pe_entry) /* Relocate efi_config->call() */ leal efi32_config(%esi), %eax - add %esi, 32(%eax) + add %esi, 40(%eax) pushl %eax call make_boot_params
@@ -108,7 +108,7 @@ ENTRY(efi32_stub_entry) /* Relocate efi_config->call() */ leal efi32_config(%esi), %eax - add %esi, 32(%eax) + add %esi, 40(%eax) pushl %eax 2: call efi_main
@@ -264,7 +264,7 @@ ENDPROC(startup_32) #ifdef CONFIG_EFI_STUB .data efi32_config: - .fill 4,8,0 + .fill 5,8,0 .long efi_call_phys .long 0 .byte 0
arch/x86/boot/compressed/head_64.S +4 -4
@@ -264,7 +264,7 @@ ENTRY(efi_pe_entry) /* * Relocate efi_config->call(). */ - addq %rbp, efi64_config+32(%rip) + addq %rbp, efi64_config+40(%rip) movq %rax, %rdi call make_boot_params
@@ -284,7 +284,7 @@ ENTRY(efi_pe_entry) * Relocate efi_config->call(). */ movq efi_config(%rip), %rax - addq %rbp, 32(%rax) + addq %rbp, 40(%rax) 2: movq efi_config(%rip), %rdi call efi_main
@@ -456,14 +456,14 @@ ENDPROC(efi64_stub_entry) #ifdef CONFIG_EFI_MIXED .global efi32_config efi32_config: - .fill 4,8,0 + .fill 5,8,0 .quad efi64_thunk .byte 0 #endif .global efi64_config efi64_config: - .fill 4,8,0 + .fill 5,8,0 .quad efi_call .byte 1 #endif /* CONFIG_EFI_STUB */
arch/x86/include/asm/efi.h +5 -0
@@ -191,6 +191,7 @@ static inline efi_status_t efi_thunk_set_virtual_address_map(struct efi_config {u64 image_handle;u64 table; +u64 runtime_services;u64 boot_services;u64 text_output;efi_status_t (*call)(unsigned long , ...);
@@ -226,6 +227,10 @@ static inline bool efi_is_64bit(void)#define __efi_call_early (f, ...) \ __efi_early()->call((unsigned long)f, __VA_ARGS__); +#define efi_call_runtime (f, ...) \ + __efi_early()->call(efi_table_attr(efi_runtime_services, f, \ + __efi_early()->runtime_services), __VA_ARGS__) +extern bool efi_reboot_required (void );#else
arch/x86/include/uapi/asm/bootparam.h +2 -1
@@ -135,7 +135,8 @@ struct boot_params {__u8 eddbuf_entries;/* 0x1e9 */ __u8 edd_mbr_sig_buf_entries;/* 0x1ea */ __u8 kbd_status;/* 0x1eb */ -__u8 _pad5[3 ];/* 0x1ec */ +__u8 secure_boot;/* 0x1ec */ +__u8 _pad5[2 ];/* 0x1ed */ /* * The sentinel is set to a nonzero value (0xff) in header.S. *
arch/x86/kernel/acpi/boot.c +9 -0
@@ -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;
arch/x86/kernel/asm-offsets.c +1 -0
@@ -81,6 +81,7 @@ void common(void) {BLANK ();OFFSET (BP_scratch, boot_params, scratch); +OFFSET (BP_secure_boot, boot_params, secure_boot);OFFSET (BP_loadflags, boot_params, hdr.loadflags);OFFSET (BP_hardware_subarch, boot_params, hdr.hardware_subarch);OFFSET (BP_version, boot_params, hdr.version);
arch/x86/kernel/setup.c +14 -0
@@ -1176,6 +1176,20 @@ void __init setup_arch(char **cmdline_p)/* Allocate bigger log buffer */ setup_log_buf (1 ); +if (efi_enabled (EFI_BOOT )) { +switch (boot_params.secure_boot) { +case efi_secureboot_mode_disabled: +pr_info ("Secure boot disabled\n" ); +break ; +case efi_secureboot_mode_enabled: +pr_info ("Secure boot enabled\n" ); +break ; +default : +pr_info ("Secure boot could not be determined\n" ); +break ; + } + } +reserve_initrd ();acpi_table_upgrade ();
arch/x86/platform/efi/efi-bgrt.c +25 -34
99 lines not on this page · raw message
arch/x86/platform/efi/efi.c +5 -5
@@ -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)) {
arch/x86/platform/efi/efi_64.c +54 -10
85 lines not on this page · raw message
drivers/acpi/bgrt.c +20 -8
@@ -15,40 +15,41 @@#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);
drivers/firmware/efi/arm-init.c +0 -1
@@ -250,7 +250,6 @@ void __init efi_init(void) }reserve_regions (); -efi_memattr_init ();efi_esrt_init ();efi_memmap_unmap ();
drivers/firmware/efi/efi.c +2 -0
@@ -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;
drivers/firmware/efi/esrt.c +1 -1
@@ -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 ; }
drivers/firmware/efi/libstub/Makefile +17 -9
@@ -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
@@ -28,7 +28,7 @@ OBJECT_FILES_NON_STANDARD := y # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. KCOV_INSTRUMENT := n -lib-y := efi-stub-helper.o gop.o +lib-y := efi-stub-helper.o gop.o secureboot.o # include the stub's generic dependencies from lib/ when building for ARM/arm64 arm-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c sort.c
@@ -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
drivers/firmware/efi/libstub/arm-stub.c +6 -126
159 lines not on this page · raw message
drivers/firmware/efi/libstub/efi-stub-helper.c +73 -1
92 lines not on this page · raw message
drivers/firmware/efi/libstub/efistub.h +0 -8
@@ -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,
drivers/firmware/efi/libstub/secureboot.c new file +84 -0
84 lines not on this page · raw message
drivers/firmware/efi/memattr.c +5 -1
@@ -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;
include/linux/efi-bgrt.h +5 -6
@@ -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 */
include/linux/efi.h +34 -22
99 lines not on this page · raw message
init/main.c +0 -1
@@ -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 (); }