1. 17 6月, 2020 1 次提交
    • A
      efi/libstub: arm: Print CPU boot mode and MMU state at boot · 2a55280a
      Ard Biesheuvel 提交于
      On 32-bit ARM, we may boot at HYP mode, or with the MMU and caches off
      (or both), even though the EFI spec does not actually support this.
      While booting at HYP mode is something we might tolerate, fiddling
      with the caches is a more serious issue, as disabling the caches is
      tricky to do safely from C code, and running without the Dcache makes
      it impossible to support unaligned memory accesses, which is another
      explicit requirement imposed by the EFI spec.
      
      So take note of the CPU mode and MMU state in the EFI stub diagnostic
      output so that we can easily diagnose any issues that may arise from
      this. E.g.,
      
        EFI stub: Entering in SVC mode with MMU enabled
      
      Also, capture the CPSR and SCTLR system register values at EFI stub
      entry, and after ExitBootServices() returns, and check whether the
      MMU and Dcache were disabled at any point. If this is the case, a
      diagnostic message like the following will be emitted:
      
        efi: [Firmware Bug]: EFI stub was entered with MMU and Dcache disabled, please fix your firmware!
        efi: CPSR at EFI stub entry        : 0x600001d3
        efi: SCTLR at EFI stub entry       : 0x00c51838
        efi: CPSR after ExitBootServices() : 0x600001d3
        efi: SCTLR after ExitBootServices(): 0x00c50838
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      Reviewed-by: NLeif Lindholm <leif@nuviainc.com>
      2a55280a
  2. 15 6月, 2020 1 次提交
    • G
      efi: Replace zero-length array and use struct_size() helper · 29637951
      Gustavo A. R. Silva 提交于
      The current codebase makes use of the zero-length array language
      extension to the C90 standard, but the preferred mechanism to declare
      variable-length types such as these ones is a flexible array member[1][2],
      introduced in C99:
      
      struct foo {
              int stuff;
              struct boo array[];
      };
      
      By making use of the mechanism above, we will get a compiler warning
      in case the flexible array does not occur last in the structure, which
      will help us prevent some kind of undefined behavior bugs from being
      inadvertently introduced[3] to the codebase from now on.
      
      Also, notice that, dynamic memory allocations won't be affected by
      this change:
      
      "Flexible array members have incomplete type, and so the sizeof operator
      may not be applied. As a quirk of the original implementation of
      zero-length arrays, sizeof evaluates to zero."[1]
      
      sizeof(flexible-array-member) triggers a warning because flexible array
      members have incomplete type[1]. There are some instances of code in
      which the sizeof operator is being incorrectly/erroneously applied to
      zero-length arrays and the result is zero. Such instances may be hiding
      some bugs. So, this work (flexible-array member conversions) will also
      help to get completely rid of those sorts of issues.
      
      Lastly, make use of the sizeof_field() helper instead of an open-coded
      version.
      
      This issue was found with the help of Coccinelle and audited _manually_.
      
      [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
      [2] https://github.com/KSPP/linux/issues/21
      [3] commit 76497732 ("cxgb3/l2t: Fix undefined behaviour")
      Signed-off-by: NGustavo A. R. Silva <gustavoars@kernel.org>
      Reviewed-by: NKees Cook <keescook@chromium.org>
      Link: https://lore.kernel.org/r/20200527171425.GA4053@embeddedorSigned-off-by: NArd Biesheuvel <ardb@kernel.org>
      29637951
  3. 21 5月, 2020 2 次提交
  4. 17 5月, 2020 1 次提交
  5. 24 4月, 2020 1 次提交
    • A
      efi: Clean up config table description arrays · 4e9a0f73
      Ard Biesheuvel 提交于
      Increase legibility by adding whitespace to the efi_config_table_type_t
      arrays that describe which EFI config tables we look for when going over
      the firmware provided list. While at it, replace the 'name' char pointer
      with a char array, which is more space efficient on relocatable 64-bit
      kernels, as it avoids a 8 byte pointer and the associated relocation
      data (24 bytes when using RELA format)
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      4e9a0f73
  6. 27 3月, 2020 1 次提交
  7. 03 3月, 2020 2 次提交
    • H
      efi: Add embedded peripheral firmware support · f0df68d5
      Hans de Goede 提交于
      Just like with PCI options ROMs, which we save in the setup_efi_pci*
      functions from arch/x86/boot/compressed/eboot.c, the EFI code / ROM itself
      sometimes may contain data which is useful/necessary for peripheral drivers
      to have access to.
      
      Specifically the EFI code may contain an embedded copy of firmware which
      needs to be (re)loaded into the peripheral. Normally such firmware would be
      part of linux-firmware, but in some cases this is not feasible, for 2
      reasons:
      
      1) The firmware is customized for a specific use-case of the chipset / use
      with a specific hardware model, so we cannot have a single firmware file
      for the chipset. E.g. touchscreen controller firmwares are compiled
      specifically for the hardware model they are used with, as they are
      calibrated for a specific model digitizer.
      
      2) Despite repeated attempts we have failed to get permission to
      redistribute the firmware. This is especially a problem with customized
      firmwares, these get created by the chip vendor for a specific ODM and the
      copyright may partially belong with the ODM, so the chip vendor cannot
      give a blanket permission to distribute these.
      
      This commit adds support for finding peripheral firmware embedded in the
      EFI code and makes the found firmware available through the new
      efi_get_embedded_fw() function.
      
      Support for loading these firmwares through the standard firmware loading
      mechanism is added in a follow-up commit in this patch-series.
      
      Note we check the EFI_BOOT_SERVICES_CODE for embedded firmware near the end
      of start_kernel(), just before calling rest_init(), this is on purpose
      because the typical EFI_BOOT_SERVICES_CODE memory-segment is too large for
      early_memremap(), so the check must be done after mm_init(). This relies
      on EFI_BOOT_SERVICES_CODE not being free-ed until efi_free_boot_services()
      is called, which means that this will only work on x86 for now.
      Reported-by: NDave Olsthoorn <dave@bewaar.me>
      Suggested-by: NPeter Jones <pjones@redhat.com>
      Acked-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NHans de Goede <hdegoede@redhat.com>
      Link: https://lore.kernel.org/r/20200115163554.101315-3-hdegoede@redhat.comSigned-off-by: NArd Biesheuvel <ardb@kernel.org>
      f0df68d5
    • H
      efi: Export boot-services code and data as debugfs-blobs · 0e72a6a3
      Hans de Goede 提交于
      Sometimes it is useful to be able to dump the efi boot-services code and
      data. This commit adds these as debugfs-blobs to /sys/kernel/debug/efi,
      but only if efi=debug is passed on the kernel-commandline as this requires
      not freeing those memory-regions, which costs 20+ MB of RAM.
      Reviewed-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Acked-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NHans de Goede <hdegoede@redhat.com>
      Link: https://lore.kernel.org/r/20200115163554.101315-2-hdegoede@redhat.comSigned-off-by: NArd Biesheuvel <ardb@kernel.org>
      0e72a6a3
  8. 29 2月, 2020 1 次提交
  9. 24 2月, 2020 21 次提交
    • A
      efi: Add support for EFI_RT_PROPERTIES table · fe4db90a
      Ard Biesheuvel 提交于
      Take the newly introduced EFI_RT_PROPERTIES_TABLE configuration table
      into account, which carries a mask of which EFI runtime services are
      still functional after ExitBootServices() has been called by the OS.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      fe4db90a
    • A
      efi: Store mask of supported runtime services in struct efi · 96a3dd3d
      Ard Biesheuvel 提交于
      Revision 2.8 of the UEFI spec introduces provisions for firmware to
      advertise lack of support for certain runtime services at OS runtime.
      Let's store this mask in struct efi for easy access.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      96a3dd3d
    • A
      efi/arm: Move FDT specific definitions into fdtparams.c · 3b2e4b4c
      Ard Biesheuvel 提交于
      Push the FDT params specific types and definition into fdtparams.c,
      and instead, pass a reference to the memory map data structure and
      populate it directly, and return the system table address as the
      return value.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      3b2e4b4c
    • A
      efi/x86: Drop 'systab' member from struct efi · fd268304
      Ard Biesheuvel 提交于
      The systab member in struct efi has outlived its usefulness, now that
      we have better ways to access the only piece of information we are
      interested in after init, which is the EFI runtime services table
      address. So instead of instantiating a doctored copy at early boot
      with lots of mangled values, and switching the pointer when switching
      into virtual mode, let's grab the values we need directly, and get
      rid of the systab pointer entirely.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      fd268304
    • A
      efi: Add 'runtime' pointer to struct efi · 59f2a619
      Ard Biesheuvel 提交于
      Instead of going through the EFI system table each time, just copy the
      runtime services table pointer into struct efi directly. This is the
      last use of the system table pointer in struct efi, allowing us to
      drop it in a future patch, along with a fair amount of quirky handling
      of the translated address.
      
      Note that usually, the runtime services pointer changes value during
      the call to SetVirtualAddressMap(), so grab the updated value as soon
      as that call returns. (Mixed mode uses a 1:1 mapping, and kexec boot
      enters with the updated address in the system table, so in those cases,
      we don't need to do anything here)
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      59f2a619
    • A
      efi/x86: Make fw_vendor, config_table and runtime sysfs nodes x86 specific · 9cd437ac
      Ard Biesheuvel 提交于
      There is some code that exposes physical addresses of certain parts of
      the EFI firmware implementation via sysfs nodes. These nodes are only
      used on x86, and are of dubious value to begin with, so let's move
      their handling into the x86 arch code.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      9cd437ac
    • A
      efi: Clean up config_parse_tables() · 06c0bd93
      Ard Biesheuvel 提交于
      config_parse_tables() is a jumble of pointer arithmetic, due to the
      fact that on x86, we may be dealing with firmware whose native word
      size differs from the kernel's.
      
      This is not a concern on other architectures, and doesn't quite
      justify the state of the code, so let's clean it up by adding a
      non-x86 code path, constifying statically allocated tables and
      replacing preprocessor conditionals with IS_ENABLED() checks.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      06c0bd93
    • 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
  10. 20 1月, 2020 3 次提交
  11. 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
  12. 25 12月, 2019 3 次提交