Merge branch 'efi-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 7 Sep 2017 16:42:35 +0000 (09:42 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 7 Sep 2017 16:42:35 +0000 (09:42 -0700)
Pull EFI updates from Ingo Molnar:
 "The main changes in this cycle were:

   - Transparently fall back to other poweroff method(s) if EFI poweroff
     fails (and returns)

   - Use separate PE/COFF section headers for the RX and RW parts of the
     ARM stub loader so that the firmware can use strict mapping
     permissions

   - Add support for requesting the firmware to wipe RAM at warm reboot

   - Increase the size of the random seed obtained from UEFI so CRNG
     fast init can complete earlier

   - Update the EFI framebuffer address if it points to a BAR that gets
     moved by the PCI resource allocation code

   - Enable "reset attack mitigation" of TPM environments: this is
     enabled if the kernel is configured with
     CONFIG_RESET_ATTACK_MITIGATION=y.

   - Clang related fixes

   - Misc cleanups, constification, refactoring, etc"

* 'efi-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  efi/bgrt: Use efi_mem_type()
  efi: Move efi_mem_type() to common code
  efi/reboot: Make function pointer orig_pm_power_off static
  efi/random: Increase size of firmware supplied randomness
  efi/libstub: Enable reset attack mitigation
  firmware/efi/esrt: Constify attribute_group structures
  firmware/efi: Constify attribute_group structures
  firmware/dcdbas: Constify attribute_group structures
  arm/efi: Split zImage code and data into separate PE/COFF sections
  arm/efi: Replace open coded constants with symbolic ones
  arm/efi: Remove pointless dummy .reloc section
  arm/efi: Remove forbidden values from the PE/COFF header
  drivers/fbdev/efifb: Allow BAR to be moved instead of claiming it
  efi/reboot: Fall back to original power-off method if EFI_RESET_SHUTDOWN returns
  efi/arm/arm64: Add missing assignment of efi.config_table
  efi/libstub/arm64: Set -fpie when building the EFI stub
  efi/libstub/arm64: Force 'hidden' visibility for section markers
  efi/libstub/arm64: Use hidden attribute for struct screen_info reference
  efi/arm: Don't mark ACPI reclaim memory as MEMBLOCK_NOMAP

1  2 
arch/arm64/include/asm/efi.h
arch/x86/boot/compressed/eboot.c
drivers/firmware/efi/libstub/arm64-stub.c
include/linux/efi.h

@@@ -3,9 -3,7 +3,9 @@@
  
  #include <asm/boot.h>
  #include <asm/cpufeature.h>
 +#include <asm/fpsimd.h>
  #include <asm/io.h>
 +#include <asm/memory.h>
  #include <asm/mmu_context.h>
  #include <asm/neon.h>
  #include <asm/ptrace.h>
@@@ -22,8 -20,8 +22,8 @@@ int efi_set_mapping_permissions(struct 
  
  #define arch_efi_call_virt_setup()                                    \
  ({                                                                    \
 -      kernel_neon_begin();                                            \
        efi_virtmap_load();                                             \
 +      __efi_fpsimd_begin();                                           \
  })
  
  #define arch_efi_call_virt(p, f, args...)                             \
@@@ -35,8 -33,8 +35,8 @@@
  
  #define arch_efi_call_virt_teardown()                                 \
  ({                                                                    \
 +      __efi_fpsimd_end();                                             \
        efi_virtmap_unload();                                           \
 -      kernel_neon_end();                                              \
  })
  
  #define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
   */
  #define EFI_FDT_ALIGN SZ_2M   /* used by allocate_new_fdt_and_exit_boot() */
  
 +/*
 + * In some configurations (e.g. VMAP_STACK && 64K pages), stacks built into the
 + * kernel need greater alignment than we require the segments to be padded to.
 + */
 +#define EFI_KIMG_ALIGN        \
 +      (SEGMENT_ALIGN > THREAD_ALIGN ? SEGMENT_ALIGN : THREAD_ALIGN)
 +
  /* on arm64, the FDT may be located anywhere in system RAM */
  static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base)
  {
@@@ -90,6 -81,9 +90,9 @@@ static inline unsigned long efi_get_max
  #define alloc_screen_info(x...)               &screen_info
  #define free_screen_info(x...)
  
+ /* redeclare as 'hidden' so the compiler will generate relative references */
+ extern struct screen_info screen_info __attribute__((__visibility__("hidden")));
  static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt)
  {
  }
@@@ -767,7 -767,7 +767,7 @@@ static efi_status_t setup_e820(struct b
                m |= (u64)efi->efi_memmap_hi << 32;
  #endif
  
 -              d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
 +              d = efi_early_memdesc_ptr(m, efi->efi_memdesc_size, i);
                switch (d->type) {
                case EFI_RESERVED_TYPE:
                case EFI_RUNTIME_SERVICES_CODE:
@@@ -996,6 -996,9 +996,9 @@@ struct boot_params *efi_main(struct efi
         */
        if (boot_params->secure_boot == efi_secureboot_mode_unset)
                boot_params->secure_boot = efi_get_secureboot(sys_table);
+       /* Ask the firmware to clear memory on unclean shutdown */
+       efi_enable_reset_attack_mitigation(sys_table);
  
        setup_graphics(boot_params);
  
                desc->s = DESC_TYPE_CODE_DATA;
                desc->dpl = 0;
                desc->p = 1;
 -              desc->limit = 0xf;
 +              desc->limit1 = 0xf;
                desc->avl = 0;
                desc->l = 0;
                desc->d = SEG_OP_SIZE_32BIT;
        desc->s = DESC_TYPE_CODE_DATA;
        desc->dpl = 0;
        desc->p = 1;
 -      desc->limit = 0xf;
 +      desc->limit1 = 0xf;
        desc->avl = 0;
        if (IS_ENABLED(CONFIG_X86_64)) {
                desc->l = 1;
        desc->s = DESC_TYPE_CODE_DATA;
        desc->dpl = 0;
        desc->p = 1;
 -      desc->limit = 0xf;
 +      desc->limit1 = 0xf;
        desc->avl = 0;
        desc->l = 0;
        desc->d = SEG_OP_SIZE_32BIT;
                desc->s = 0;
                desc->dpl = 0;
                desc->p = 1;
 -              desc->limit = 0x0;
 +              desc->limit1 = 0x0;
                desc->avl = 0;
                desc->l = 0;
                desc->d = 0;
@@@ -9,10 -9,17 +9,18 @@@
   * published by the Free Software Foundation.
   *
   */
+ /*
+  * To prevent the compiler from emitting GOT-indirected (and thus absolute)
+  * references to the section markers, override their visibility as 'hidden'
+  */
+ #pragma GCC visibility push(hidden)
+ #include <asm/sections.h>
+ #pragma GCC visibility pop
  #include <linux/efi.h>
  #include <asm/efi.h>
- #include <asm/sections.h>
 +#include <asm/memory.h>
  #include <asm/sysreg.h>
  
  #include "efistub.h"
@@@ -82,10 -89,9 +90,10 @@@ efi_status_t handle_kernel_image(efi_sy
                /*
                 * If CONFIG_DEBUG_ALIGN_RODATA is not set, produce a
                 * displacement in the interval [0, MIN_KIMG_ALIGN) that
 -               * is a multiple of the minimal segment alignment (SZ_64K)
 +               * doesn't violate this kernel's de-facto alignment
 +               * constraints.
                 */
 -              u32 mask = (MIN_KIMG_ALIGN - 1) & ~(SZ_64K - 1);
 +              u32 mask = (MIN_KIMG_ALIGN - 1) & ~(EFI_KIMG_ALIGN - 1);
                u32 offset = !IS_ENABLED(CONFIG_DEBUG_ALIGN_RODATA) ?
                             (phys_seed >> 32) & mask : TEXT_OFFSET;
  
diff --combined include/linux/efi.h
@@@ -1020,28 -1020,6 +1020,28 @@@ extern int efi_memattr_init(void)
  extern int efi_memattr_apply_permissions(struct mm_struct *mm,
                                         efi_memattr_perm_setter fn);
  
 +/*
 + * efi_early_memdesc_ptr - get the n-th EFI memmap descriptor
 + * @map: the start of efi memmap
 + * @desc_size: the size of space for each EFI memmap descriptor
 + * @n: the index of efi memmap descriptor
 + *
 + * EFI boot service provides the GetMemoryMap() function to get a copy of the
 + * current memory map which is an array of memory descriptors, each of
 + * which describes a contiguous block of memory. It also gets the size of the
 + * map, and the size of each descriptor, etc.
 + *
 + * Note that per section 6.2 of UEFI Spec 2.6 Errata A, the returned size of
 + * each descriptor might not be equal to sizeof(efi_memory_memdesc_t),
 + * since efi_memory_memdesc_t may be extended in the future. Thus the OS
 + * MUST use the returned size of the descriptor to find the start of each
 + * efi_memory_memdesc_t in the memory map array. This should only be used
 + * during bootup since for_each_efi_memory_desc_xxx() is available after the
 + * kernel initializes the EFI subsystem to set up struct efi_memory_map.
 + */
 +#define efi_early_memdesc_ptr(map, desc_size, n)                      \
 +      (efi_memory_desc_t *)((void *)(map) + ((n) * (desc_size)))
 +
  /* Iterate through an efi_memory_map */
  #define for_each_efi_memory_desc_in_map(m, md)                                   \
        for ((md) = (m)->map;                                              \
@@@ -1526,6 -1504,13 +1526,13 @@@ enum efi_secureboot_mode 
  };
  enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table);
  
+ #ifdef CONFIG_RESET_ATTACK_MITIGATION
+ void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg);
+ #else
+ static inline void
+ efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg) { }
+ #endif
  /*
   * Arch code can implement the following three template macros, avoiding
   * reptition for the void/non-void return cases of {__,}efi_call_virt():
@@@ -1586,6 -1571,8 +1593,8 @@@ efi_status_t efi_exit_boot_services(efi
                                    void *priv,
                                    efi_exit_boot_map_processing priv_func);
  
+ #define EFI_RANDOM_SEED_SIZE          64U
  struct linux_efi_random_seed {
        u32     size;
        u8      bits[];