1. 08 3月, 2020 3 次提交
  2. 24 2月, 2020 11 次提交
    • A
      efi/x86: Implement mixed mode boot without the handover protocol · 17054f49
      Ard Biesheuvel 提交于
      Add support for booting 64-bit x86 kernels from 32-bit firmware running
      on 64-bit capable CPUs without requiring the bootloader to implement
      the EFI handover protocol or allocate the setup block, etc etc, all of
      which can be done by the stub itself, using code that already exists.
      
      Instead, create an ordinary EFI application entrypoint but implemented
      in 32-bit code [so that it can be invoked by 32-bit firmware], and stash
      the address of this 32-bit entrypoint in the .compat section where the
      bootloader can find it.
      
      Note that we use the setup block embedded in the binary to go through
      startup_32(), but it gets reallocated and copied in efi_pe_entry(),
      using the same code that runs when the x86 kernel is booted in EFI
      mode from native firmware. This requires the loaded image protocol to
      be installed on the kernel image's EFI handle, and point to the kernel
      image itself and not to its loader. This, in turn, requires the
      bootloader to use the LoadImage() boot service to load the 64-bit
      image from 32-bit firmware, which is in fact supported by firmware
      based on EDK2. (Only StartImage() will fail, and instead, the newly
      added entrypoint needs to be invoked)
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      17054f49
    • A
      efi/libstub/x86: Use Exit() boot service to exit the stub on errors · 3b8f44fc
      Ard Biesheuvel 提交于
      Currently, we either return with an error [from efi_pe_entry()] or
      enter a deadloop [in efi_main()] if any fatal errors occur during
      execution of the EFI stub. Let's switch to calling the Exit() EFI boot
      service instead in both cases, so that we
      a) can get rid of the deadloop, and simply return to the boot manager
         if any errors occur during execution of the stub, including during
         the call to ExitBootServices(),
      b) can also return cleanly from efi_pe_entry() or efi_main() in mixed
         mode, once we introduce support for LoadImage/StartImage based mixed
         mode in the next patch.
      
      Note that on systems running downstream GRUBs [which do not use LoadImage
      or StartImage to boot the kernel, and instead, pass their own image
      handle as the loaded image handle], calling Exit() will exit from GRUB
      rather than from the kernel, but this is a tolerable side effect.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      3b8f44fc
    • A
      efi/libstub/x86: Make loaded_image protocol handling mixed mode safe · f7b85b33
      Ard Biesheuvel 提交于
      Add the definitions and use the special wrapper so that the loaded_image
      UEFI protocol can be safely used from mixed mode.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      f7b85b33
    • A
      efi/libstub: Take noinitrd cmdline argument into account for devpath initrd · 79d3219d
      Ard Biesheuvel 提交于
      One of the advantages of using what basically amounts to a callback
      interface into the bootloader for loading the initrd is that it provides
      a natural place for the bootloader or firmware to measure the initrd
      contents while they are being passed to the kernel.
      
      Unfortunately, this is not a guarantee that the initrd will in fact be
      loaded and its /init invoked by the kernel, since the command line may
      contain the 'noinitrd' option, in which case the initrd is ignored, but
      this will not be reflected in the PCR that covers the initrd measurement.
      
      This could be addressed by measuring the command line as well, and
      including that PCR in the attestation policy, but this locks down the
      command line completely, which may be too restrictive.
      
      So let's take the noinitrd argument into account in the stub, too. This
      forces any PCR that covers the initrd to assume a different value when
      noinitrd is passed, allowing an attestation policy to disregard the
      command line if there is no need to take its measurement into account
      for other reasons.
      
      As Peter points out, this would still require the agent that takes the
      measurements to measure a separator event into the PCR in question at
      ExitBootServices() time, to prevent replay attacks using the known
      measurement from the TPM log.
      
      Cc: Peter Jones <pjones@redhat.com>
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      79d3219d
    • A
      efi/libstub: Add support for loading the initrd from a device path · ec93fc37
      Ard Biesheuvel 提交于
      There are currently two ways to specify the initrd to be passed to the
      Linux kernel when booting via the EFI stub:
      - it can be passed as a initrd= command line option when doing a pure PE
        boot (as opposed to the EFI handover protocol that exists for x86)
      - otherwise, the bootloader or firmware can load the initrd into memory,
        and pass the address and size via the bootparams struct (x86) or
        device tree (ARM)
      
      In the first case, we are limited to loading from the same file system
      that the kernel was loaded from, and it is also problematic in a trusted
      boot context, given that we cannot easily protect the command line from
      tampering without either adding complicated white/blacklisting of boot
      arguments or locking down the command line altogether.
      
      In the second case, we force the bootloader to duplicate knowledge about
      the boot protocol which is already encoded in the stub, and which may be
      subject to change over time, e.g., bootparams struct definitions, memory
      allocation/alignment requirements for the placement of the initrd etc etc.
      In the ARM case, it also requires the bootloader to modify the hardware
      description provided by the firmware, as it is passed in the same file.
      On systems where the initrd is measured after loading, it creates a time
      window where the initrd contents might be manipulated in memory before
      handing over to the kernel.
      
      Address these concerns by adding support for loading the initrd into
      memory by invoking the EFI LoadFile2 protocol installed on a vendor
      GUIDed device path that specifically designates a Linux initrd.
      This addresses the above concerns, by putting the EFI stub in charge of
      placement in memory and of passing the base and size to the kernel proper
      (via whatever means it desires) while still leaving it up to the firmware
      or bootloader to obtain the file contents, potentially from other file
      systems than the one the kernel itself was loaded from. On platforms that
      implement measured boot, it permits the firmware to take the measurement
      right before the kernel actually consumes the contents.
      Acked-by: NLaszlo Ersek <lersek@redhat.com>
      Tested-by: NIlias Apalodimas <ilias.apalodimas@linaro.org>
      Acked-by: NIlias Apalodimas <ilias.apalodimas@linaro.org>
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      ec93fc37
    • A
      efi/libstub: Clean up command line parsing routine · 91d150c0
      Ard Biesheuvel 提交于
      We currently parse the command non-destructively, to avoid having to
      allocate memory for a copy before passing it to the standard parsing
      routines that are used by the core kernel, and which modify the input
      to delineate the parsed tokens with NUL characters.
      
      Instead, we call strstr() and strncmp() to go over the input multiple
      times, and match prefixes rather than tokens, which implies that we
      would match, e.g., 'nokaslrfoo' in the stub and disable KASLR, while
      the kernel would disregard the option and run with KASLR enabled.
      
      In order to avoid having to reason about whether and how this behavior
      may be abused, let's clean up the parsing routines, and rebuild them
      on top of the existing helpers.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      91d150c0
    • A
      efi/libstub: Take soft and hard memory limits into account for initrd loading · 31f5e546
      Ard Biesheuvel 提交于
      On x86, the preferred load address of the initrd is still below 4 GB,
      even though in some cases, we can cope with an initrd that is loaded
      above that.
      
      To simplify the code, and to make it more straightforward to introduce
      other ways to load the initrd, pass the soft and hard memory limits at
      the same time, and let the code handling the initrd= command line option
      deal with this.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      31f5e546
    • A
      efi/libstub: Rewrite file I/O routine · 9302c1bb
      Ard Biesheuvel 提交于
      The file I/O routine that is used to load initrd or dtb files from
      the EFI system partition suffers from a few issues:
      - it converts the u8[] command line back to a UTF-16 string, which is
        pointless since we only handle initrd or dtb arguments provided via
        the loaded image protocol anyway, which is where we got the UTF-16[]
        command line from in the first place when booting via the PE entry
        point,
      - in the far majority of cases, only a single initrd= option is present,
        but it optimizes for multiple options, by going over the command line
        twice, allocating heap buffers for dynamically sized arrays, etc.
      - the coding style is hard to follow, with few comments, and all logic
        including string parsing etc all combined in a single routine.
      
      Let's fix this by rewriting most of it, based on the idea that in the
      case of multiple initrds, we can just allocate a new, bigger buffer
      and copy over the data before freeing the old one.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      9302c1bb
    • A
      efi/libstub/x86: Permit cmdline data to be allocated above 4 GB · 1e45bf73
      Ard Biesheuvel 提交于
      We now support cmdline data that is located in memory that is not
      32-bit addressable, so relax the allocation limit on systems where
      this feature is enabled.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      1e45bf73
    • A
      efi/libstub/x86: Permit bootparams struct to be allocated above 4 GB · 6a4db9bf
      Ard Biesheuvel 提交于
      We now support bootparams structures that are located in memory that
      is not 32-bit addressable, so relax the allocation limit on systems
      where this feature is enabled.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      6a4db9bf
    • A
      efi/libstub/x86: Incorporate eboot.c into libstub · c2d0b470
      Ard Biesheuvel 提交于
      Most of the EFI stub source files of all architectures reside under
      drivers/firmware/efi/libstub, where they share a Makefile with special
      CFLAGS and an include file with declarations that are only relevant
      for stub code.
      
      Currently, we carry a lot of stub specific stuff in linux/efi.h only
      because eboot.c in arch/x86 needs them as well. So let's move eboot.c
      into libstub/, and move the contents of eboot.h that we still care
      about into efistub.h
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      c2d0b470
  3. 23 2月, 2020 4 次提交
  4. 25 1月, 2020 1 次提交
  5. 20 1月, 2020 2 次提交
  6. 11 1月, 2020 2 次提交
    • A
      efi/x86: Allow translating 64-bit arguments for mixed mode calls · ea7d87f9
      Arvind Sankar 提交于
      Introduce the ability to define macros to perform argument translation
      for the calls that need it, and define them for the boot services that
      we currently use.
      
      When calling 32-bit firmware methods in mixed mode, all output
      parameters that are 32-bit according to the firmware, but 64-bit in the
      kernel (ie OUT UINTN * or OUT VOID **) must be initialized in the
      kernel, or the upper 32 bits may contain garbage. Define macros that
      zero out the upper 32 bits of the output before invoking the firmware
      method.
      
      When a 32-bit EFI call takes 64-bit arguments, the mixed-mode call must
      push the two 32-bit halves as separate arguments onto the stack. This
      can be achieved by splitting the argument into its two halves when
      calling the assembler thunk. Define a macro to do this for the
      free_pages boot service.
      Signed-off-by: NArvind Sankar <nivedita@alum.mit.edu>
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      Cc: Andy Lutomirski <luto@kernel.org>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Matthew Garrett <mjg59@google.com>
      Cc: linux-efi@vger.kernel.org
      Link: https://lkml.kernel.org/r/20200103113953.9571-17-ardb@kernel.orgSigned-off-by: NIngo Molnar <mingo@kernel.org>
      ea7d87f9
    • A
      efi/libstub/x86: Force 'hidden' visibility for extern declarations · bc7c9d62
      Ard Biesheuvel 提交于
      Commit c3710de5 ("efi/libstub/x86: Drop __efi_early() export and
      efi_config struct") introduced a reference from C code in eboot.c to
      the startup_32 symbol defined in the .S startup code. This results in
      a GOT based reference to startup_32, and since GOT entries carry
      absolute addresses, they need to be fixed up before they can be used.
      
      On modern toolchains (binutils 2.26 or later), this reference is
      relaxed into a R_386_GOTOFF relocation (or the analogous X86_64 one)
      which never uses the absolute address in the entry, and so we get
      away with not fixing up the GOT table before calling the EFI entry
      point. However, GCC 4.6 combined with a binutils of the era (2.24)
      will produce a true GOT indirected reference, resulting in a wrong
      value to be returned for the address of startup_32() if the boot
      code is not running at the address it was linked at.
      
      Fortunately, we can easily override this behavior, and force GCC to
      emit the GOTOFF relocations explicitly, by setting the visibility
      pragma 'hidden'.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      Cc: Andy Lutomirski <luto@kernel.org>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Arvind Sankar <nivedita@alum.mit.edu>
      Cc: Matthew Garrett <mjg59@google.com>
      Cc: linux-efi@vger.kernel.org
      Link: https://lkml.kernel.org/r/20200103113953.9571-3-ardb@kernel.orgSigned-off-by: NIngo Molnar <mingo@kernel.org>
      bc7c9d62
  7. 25 12月, 2019 13 次提交
  8. 07 11月, 2019 2 次提交
    • D
      x86/efi: EFI soft reservation to E820 enumeration · 262b45ae
      Dan Williams 提交于
      UEFI 2.8 defines an EFI_MEMORY_SP attribute bit to augment the
      interpretation of the EFI Memory Types as "reserved for a specific
      purpose".
      
      The proposed Linux behavior for specific purpose memory is that it is
      reserved for direct-access (device-dax) by default and not available for
      any kernel usage, not even as an OOM fallback.  Later, through udev
      scripts or another init mechanism, these device-dax claimed ranges can
      be reconfigured and hot-added to the available System-RAM with a unique
      node identifier. This device-dax management scheme implements "soft" in
      the "soft reserved" designation by allowing some or all of the
      reservation to be recovered as typical memory. This policy can be
      disabled at compile-time with CONFIG_EFI_SOFT_RESERVE=n, or runtime with
      efi=nosoftreserve.
      
      This patch introduces 2 new concepts at once given the entanglement
      between early boot enumeration relative to memory that can optionally be
      reserved from the kernel page allocator by default. The new concepts
      are:
      
      - E820_TYPE_SOFT_RESERVED: Upon detecting the EFI_MEMORY_SP
        attribute on EFI_CONVENTIONAL memory, update the E820 map with this
        new type. Only perform this classification if the
        CONFIG_EFI_SOFT_RESERVE=y policy is enabled, otherwise treat it as
        typical ram.
      
      - IORES_DESC_SOFT_RESERVED: Add a new I/O resource descriptor for
        a device driver to search iomem resources for application specific
        memory. Teach the iomem code to identify such ranges as "Soft Reserved".
      
      Note that the comment for do_add_efi_memmap() needed refreshing since it
      seemed to imply that the efi map might overflow the e820 table, but that
      is not an issue as of commit 7b6e4ba3 "x86/boot/e820: Clean up the
      E820_X_MAX definition" that removed the 128 entry limit for
      e820__range_add().
      
      A follow-on change integrates parsing of the ACPI HMAT to identify the
      node and sub-range boundaries of EFI_MEMORY_SP designated memory. For
      now, just identify and reserve memory of this type.
      Acked-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Reported-by: Nkbuild test robot <lkp@intel.com>
      Reviewed-by: NDave Hansen <dave.hansen@linux.intel.com>
      Signed-off-by: NDan Williams <dan.j.williams@intel.com>
      Acked-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      262b45ae
    • D
      x86: efi/random: Invoke EFI_RNG_PROTOCOL to seed the UEFI RNG table · 0d959814
      Dominik Brodowski 提交于
      Invoke the EFI_RNG_PROTOCOL protocol in the context of the x86 EFI stub,
      same as is done on arm/arm64 since commit 568bc4e8 ("efi/arm*/libstub:
      Invoke EFI_RNG_PROTOCOL to seed the UEFI RNG table"). Within the stub,
      a Linux-specific RNG seed UEFI config table will be seeded. The EFI routines
      in the core kernel will pick that up later, yet still early during boot,
      to seed the kernel entropy pool. If CONFIG_RANDOM_TRUST_BOOTLOADER, entropy
      is credited for this seed.
      Signed-off-by: NDominik Brodowski <linux@dominikbrodowski.net>
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      0d959814
  9. 31 10月, 2019 1 次提交
    • K
      x86, efi: Never relocate kernel below lowest acceptable address · 220dd769
      Kairui Song 提交于
      Currently, kernel fails to boot on some HyperV VMs when using EFI.
      And it's a potential issue on all x86 platforms.
      
      It's caused by broken kernel relocation on EFI systems, when below three
      conditions are met:
      
      1. Kernel image is not loaded to the default address (LOAD_PHYSICAL_ADDR)
         by the loader.
      2. There isn't enough room to contain the kernel, starting from the
         default load address (eg. something else occupied part the region).
      3. In the memmap provided by EFI firmware, there is a memory region
         starts below LOAD_PHYSICAL_ADDR, and suitable for containing the
         kernel.
      
      EFI stub will perform a kernel relocation when condition 1 is met. But
      due to condition 2, EFI stub can't relocate kernel to the preferred
      address, so it fallback to ask EFI firmware to alloc lowest usable memory
      region, got the low region mentioned in condition 3, and relocated
      kernel there.
      
      It's incorrect to relocate the kernel below LOAD_PHYSICAL_ADDR. This
      is the lowest acceptable kernel relocation address.
      
      The first thing goes wrong is in arch/x86/boot/compressed/head_64.S.
      Kernel decompression will force use LOAD_PHYSICAL_ADDR as the output
      address if kernel is located below it. Then the relocation before
      decompression, which move kernel to the end of the decompression buffer,
      will overwrite other memory region, as there is no enough memory there.
      
      To fix it, just don't let EFI stub relocate the kernel to any address
      lower than lowest acceptable address.
      
      [ ardb: introduce efi_low_alloc_above() to reduce the scope of the change ]
      Signed-off-by: NKairui Song <kasong@redhat.com>
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Acked-by: NJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-efi@vger.kernel.org
      Link: https://lkml.kernel.org/r/20191029173755.27149-6-ardb@kernel.orgSigned-off-by: NIngo Molnar <mingo@kernel.org>
      220dd769
  10. 19 7月, 2019 1 次提交
    • Z
      x86/boot/efi: Remove unused variables · cd6697b8
      Zhenzhong Duan 提交于
      Fix gcc warnings:
      
      arch/x86/boot/compressed/eboot.c: In function 'make_boot_params':
      arch/x86/boot/compressed/eboot.c:394:6: warning: unused variable 'i' [-Wunused-variable]
        int i;
            ^
      arch/x86/boot/compressed/eboot.c:393:6: warning: unused variable 's1' [-Wunused-variable]
        u8 *s1;
            ^
      arch/x86/boot/compressed/eboot.c:392:7: warning: unused variable 's2' [-Wunused-variable]
        u16 *s2;
             ^
      arch/x86/boot/compressed/eboot.c:387:8: warning: unused variable 'options' [-Wunused-variable]
        void *options, *handle;
              ^
      arch/x86/boot/compressed/eboot.c: In function 'add_e820ext':
      arch/x86/boot/compressed/eboot.c:498:16: warning: unused variable 'size' [-Wunused-variable]
        unsigned long size;
                      ^
      arch/x86/boot/compressed/eboot.c:497:15: warning: unused variable 'status' [-Wunused-variable]
        efi_status_t status;
                     ^
      arch/x86/boot/compressed/eboot.c: In function 'exit_boot_func':
      arch/x86/boot/compressed/eboot.c:681:15: warning: unused variable 'status' [-Wunused-variable]
        efi_status_t status;
                     ^
      arch/x86/boot/compressed/eboot.c:680:8: warning: unused variable 'nr_desc' [-Wunused-variable]
        __u32 nr_desc;
              ^
      arch/x86/boot/compressed/eboot.c: In function 'efi_main':
      arch/x86/boot/compressed/eboot.c:750:22: warning: unused variable 'image' [-Wunused-variable]
        efi_loaded_image_t *image;
                            ^
      Signed-off-by: NZhenzhong Duan <zhenzhong.duan@oracle.com>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Link: https://lkml.kernel.org/r/1563282957-26898-1-git-send-email-zhenzhong.duan@oracle.com
      cd6697b8