1. 24 2月, 2020 14 次提交
    • A
      efi: Make efi_config_init() x86 only · 3a0701dc
      Ard Biesheuvel 提交于
      The efi_config_init() routine is no longer shared with ia64 so let's
      move it into the x86 arch code before making further x86 specific
      changes to it.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      3a0701dc
    • A
      efi: Merge EFI system table revision and vendor checks · 14fb4209
      Ard Biesheuvel 提交于
      We have three different versions of the code that checks the EFI system
      table revision and copies the firmware vendor string, and they are
      mostly equivalent, with the exception of the use of early_memremap_ro
      vs. __va() and the lowest major revision to warn about. Let's move this
      into common code and factor out the commonalities.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      14fb4209
    • A
      efi: Make memreserve table handling local to efi.c · b7846e6b
      Ard Biesheuvel 提交于
      There is no need for struct efi to carry the address of the memreserve
      table and share it with the world. So move it out and make it
      __initdata as well.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      b7846e6b
    • A
      efi: Move mem_attr_table out of struct efi · a17e809e
      Ard Biesheuvel 提交于
      The memory attributes table is only used at init time by the core EFI
      code, so there is no need to carry its address in struct efi that is
      shared with the world. So move it out, and make it __ro_after_init as
      well, considering that the value is set during early boot.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      a17e809e
    • A
      efi: Make rng_seed table handling local to efi.c · 5d288dbd
      Ard Biesheuvel 提交于
      Move the rng_seed table address from struct efi into a static global
      variable in efi.c, which is the only place we ever refer to it anyway.
      This reduces the footprint of struct efi, which is a r/w data structure
      that is shared with the world.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      5d288dbd
    • A
      efi: Move UGA and PROP table handling to x86 code · fd506e0c
      Ard Biesheuvel 提交于
      The UGA table is x86 specific (its handling was introduced when the
      EFI support code was modified to accommodate IA32), so there is no
      need to handle it in generic code.
      
      The EFI properties table is not strictly x86 specific, but it was
      deprecated almost immediately after having been introduced, due to
      implementation difficulties. Only x86 takes it into account today,
      and this is not going to change, so make this table x86 only as well.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      fd506e0c
    • A
      efi/ia64: Move HCDP and MPS table handling into IA64 arch code · 120540f2
      Ard Biesheuvel 提交于
      The HCDP and MPS tables are Itanium specific EFI config tables, so
      move their handling to ia64 arch code.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      120540f2
    • A
      efi: Drop handling of 'boot_info' configuration table · 50d53c58
      Ard Biesheuvel 提交于
      Some plumbing exists to handle a UEFI configuration table of type
      BOOT_INFO but since we never match it to a GUID anywhere, we never
      actually register such a table, or access it, for that matter. So
      simply drop all mentions of it.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      50d53c58
    • 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/dev-path-parser: Add struct definition for vendor type device path nodes · db8952e7
      Ard Biesheuvel 提交于
      In preparation of adding support for loading the initrd via a special
      device path, add the struct definition of a vendor GUIDed device path
      node to efi.h.
      
      Since we will be producing these data structures rather than just
      consumsing the ones instantiated by the firmware, refactor the various
      device path node definitions so we can take the size of each node using
      sizeof() rather than having to resort to opaque arithmetic in the static
      initializers.
      
      While at it, drop the #if IS_ENABLED() check for the declaration of
      efi_get_device_by_path(), which is unnecessary, and constify its first
      argument as well.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      db8952e7
    • A
      efi/libstub: Make the LoadFile EFI protocol accessible · 2931d526
      Ard Biesheuvel 提交于
      Add the protocol definitions, GUIDs and mixed mode glue so that
      the EFI loadfile protocol can be used from the stub. This will
      be used in a future patch to load the initrd.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      2931d526
    • A
      efi/libstub: Move stub specific declarations into efistub.h · 8166ec09
      Ard Biesheuvel 提交于
      Move all the declarations that are only used in stub code from
      linux/efi.h to efistub.h which is only included locally.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      8166ec09
    • A
      efi/libstub: Use consistent type names for file I/O protocols · a46a290a
      Ard Biesheuvel 提交于
      Align the naming of efi_file_io_interface_t and efi_file_handle_t with
      the UEFI spec, and call them efi_simple_file_system_protocol_t and
      efi_file_protocol_t, respectively, using the same convention we use
      for all other type definitions that originate in the UEFI spec.
      
      While at it, move the definitions to efistub.h, so they are only seen
      by code that needs them.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      a46a290a
    • A
      efi/libstub: Simplify efi_high_alloc() and rename to efi_allocate_pages() · a7495c28
      Ard Biesheuvel 提交于
      The implementation of efi_high_alloc() uses a complicated way of
      traversing the memory map to find an available region that is located
      as close as possible to the provided upper limit, and calls AllocatePages
      subsequently to create the allocation at that exact address.
      
      This is precisely what the EFI_ALLOCATE_MAX_ADDRESS allocation type
      argument to AllocatePages() does, and considering that EFI_ALLOC_ALIGN
      only exceeds EFI_PAGE_SIZE on arm64, let's use AllocatePages() directly
      and implement the alignment using code that the compiler can remove if
      it does not exceed EFI_PAGE_SIZE.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      a7495c28
  2. 20 1月, 2020 3 次提交
  3. 11 1月, 2020 3 次提交
    • M
      efi: Allow disabling PCI busmastering on bridges during boot · 4444f854
      Matthew Garrett 提交于
      Add an option to disable the busmaster bit in the control register on
      all PCI bridges before calling ExitBootServices() and passing control
      to the runtime kernel. System firmware may configure the IOMMU to prevent
      malicious PCI devices from being able to attack the OS via DMA. However,
      since firmware can't guarantee that the OS is IOMMU-aware, it will tear
      down IOMMU configuration when ExitBootServices() is called. This leaves
      a window between where a hostile device could still cause damage before
      Linux configures the IOMMU again.
      
      If CONFIG_EFI_DISABLE_PCI_DMA is enabled or "efi=disable_early_pci_dma"
      is passed on the command line, the EFI stub will clear the busmaster bit
      on all PCI bridges before ExitBootServices() is called. This will
      prevent any malicious PCI devices from being able to perform DMA until
      the kernel reenables busmastering after configuring the IOMMU.
      
      This option may cause failures with some poorly behaved hardware and
      should not be enabled without testing. The kernel commandline options
      "efi=disable_early_pci_dma" or "efi=no_disable_early_pci_dma" may be
      used to override the default. Note that PCI devices downstream from PCI
      bridges are disconnected from their drivers first, using the UEFI
      driver model API, so that DMA can be disabled safely at the bridge
      level.
      
      [ardb: disconnect PCI I/O handles first, as suggested by Arvind]
      Co-developed-by: NMatthew Garrett <mjg59@google.com>
      Signed-off-by: NMatthew Garrett <mjg59@google.com>
      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 <matthewgarrett@google.com>
      Cc: linux-efi@vger.kernel.org
      Link: https://lkml.kernel.org/r/20200103113953.9571-18-ardb@kernel.orgSigned-off-by: NIngo Molnar <mingo@kernel.org>
      4444f854
    • A
      efi/x86: Drop two near identical versions of efi_runtime_init() · 33b85447
      Ard Biesheuvel 提交于
      The routines efi_runtime_init32() and efi_runtime_init64() are
      almost indistinguishable, and the only relevant difference is
      the offset in the runtime struct from where to obtain the physical
      address of the SetVirtualAddressMap() routine.
      
      However, this address is only used once, when installing the virtual
      address map that the OS will use to invoke EFI runtime services, and
      at the time of the call, we will necessarily be running with a 1:1
      mapping, and so there is no need to do the map/unmap dance here to
      retrieve the address. In fact, in the preceding changes to these users,
      we stopped using the address recorded here entirely.
      
      So let's just get rid of all this code since it no longer serves a
      purpose. While at it, tweak the logic so that we handle unsupported
      and disable EFI runtime services in the same way, and unmap the EFI
      memory map in both cases.
      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-12-ardb@kernel.orgSigned-off-by: NIngo Molnar <mingo@kernel.org>
      33b85447
    • A
      efi/x86: Avoid redundant cast of EFI firmware service pointer · 89ed4865
      Ard Biesheuvel 提交于
      All EFI firmware call prototypes have been annotated as __efiapi,
      permitting us to attach attributes regarding the calling convention
      by overriding __efiapi to an architecture specific value.
      
      On 32-bit x86, EFI firmware calls use the plain calling convention
      where all arguments are passed via the stack, and cleaned up by the
      caller. Let's add this to the __efiapi definition so we no longer
      need to cast the function pointers before invoking them.
      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-6-ardb@kernel.orgSigned-off-by: NIngo Molnar <mingo@kernel.org>
      89ed4865
  4. 25 12月, 2019 12 次提交
  5. 08 12月, 2019 1 次提交
  6. 07 11月, 2019 4 次提交
    • D
      efi: Common enable/disable infrastructure for EFI soft reservation · b617c526
      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.
      
      As for this patch, define the common helpers to determine if the
      EFI_MEMORY_SP attribute should be honored. The determination needs to be
      made early to prevent the kernel from being loaded into soft-reserved
      memory, or otherwise allowing early allocations to land there. Follow-on
      changes are needed per architecture to leverage these helpers in their
      respective mem-init paths.
      Reviewed-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      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>
      b617c526
    • D
      x86/efi: Push EFI_MEMMAP check into leaf routines · 6950e31b
      Dan Williams 提交于
      In preparation for adding another EFI_MEMMAP dependent call that needs
      to occur before e820__memblock_setup() fixup the existing efi calls to
      check for EFI_MEMMAP internally. This ends up being cleaner than the
      alternative of checking EFI_MEMMAP multiple times in setup_arch().
      Reviewed-by: NDave Hansen <dave.hansen@linux.intel.com>
      Reviewed-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      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>
      6950e31b
    • D
      efi: Enumerate EFI_MEMORY_SP · fe3e5e65
      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 intent of this bit is to allow the OS to identify precious
      or scarce memory resources and optionally manage it separately from
      EfiConventionalMemory. As defined older OSes that do not know about this
      attribute are permitted to ignore it and the memory will be handled
      according to the OS default policy for the given memory type.
      
      In other words, this "specific purpose" hint is deliberately weaker than
      EfiReservedMemoryType in that the system continues to operate if the OS
      takes no action on the attribute. The risk of taking no action is
      potentially unwanted / unmovable kernel allocations from the designated
      resource that prevent the full realization of the "specific purpose".
      For example, consider a system with a high-bandwidth memory pool. Older
      kernels are permitted to boot and consume that memory as conventional
      "System-RAM" newer kernels may arrange for that memory to be set aside
      (soft reserved) by the system administrator for a dedicated
      high-bandwidth memory aware application to consume.
      
      Specifically, this mechanism allows for the elimination of scenarios
      where platform firmware tries to game OS policy by lying about ACPI SLIT
      values, i.e. claiming that a precious memory resource has a high
      distance to trigger the OS to avoid it by default. This reservation hint
      allows platform-firmware to instead tell the truth about performance
      characteristics by indicate to OS memory management to put immovable
      allocations elsewhere.
      
      Implement simple detection of the bit for EFI memory table dumps and
      save the kernel policy for a follow-on change.
      Reviewed-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      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>
      fe3e5e65
    • 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
  7. 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
  8. 08 8月, 2019 2 次提交