1. 27 9月, 2022 2 次提交
    • A
      efi: libstub: unify initrd loading between architectures · f4dc7fff
      Ard Biesheuvel 提交于
      Use a EFI configuration table to pass the initrd to the core kernel,
      instead of per-arch methods. This cleans up the code considerably, and
      should make it easier for architectures to get rid of their reliance on
      DT for doing EFI boot in the future.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      f4dc7fff
    • A
      efi: libstub: simplify efi_get_memory_map() and struct efi_boot_memmap · eab31265
      Ard Biesheuvel 提交于
      Currently, struct efi_boot_memmap is a struct that is passed around
      between callers of efi_get_memory_map() and the users of the resulting
      data, and which carries pointers to various variables whose values are
      provided by the EFI GetMemoryMap() boot service.
      
      This is overly complex, and it is much easier to carry these values in
      the struct itself. So turn the struct into one that carries these data
      items directly, including a flex array for the variable number of EFI
      memory descriptors that the boot service may return.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      eab31265
  2. 29 6月, 2022 1 次提交
  3. 25 6月, 2022 7 次提交
    • A
      efi: vars: Move efivar caching layer into efivarfs · 2d82e622
      Ard Biesheuvel 提交于
      Move the fiddly bits of the efivar layer into its only remaining user,
      efivarfs, and confine its use to that particular module. All other uses
      of the EFI variable store have no need for this additional layer of
      complexity, given that they either only read variables, or read and
      write variables into a separate GUIDed namespace, and cannot be used to
      manipulate EFI variables that are covered by the EFI spec and/or affect
      the boot flow.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      2d82e622
    • A
      efi: vars: Drop __efivar_entry_iter() helper which is no longer used · 5ac94136
      Ard Biesheuvel 提交于
      __efivar_entry_iter() uses a list iterator in a dubious way, i.e., it
      assumes that the iteration variable always points to an object of the
      appropriate type, even if the list traversal exhausts the list
      completely, in which case it will point somewhere in the vicinity of the
      list's anchor instead.
      
      Fortunately, we no longer use this function so we can just get rid of it
      entirely.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      5ac94136
    • A
      efi: vars: Use locking version to iterate over efivars linked lists · 3a75f9f2
      Ard Biesheuvel 提交于
      Both efivars and efivarfs uses __efivar_entry_iter() to go over the
      linked list that shadows the list of EFI variables held by the firmware,
      but fail to call the begin/end helpers that are documented as a
      prerequisite.
      
      So switch to the proper version, which is efivar_entry_iter(). Given
      that in both cases, efivar_entry_remove() is invoked with the lock held
      already, don't take the lock there anymore.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      3a75f9f2
    • A
      efi: vars: Remove deprecated 'efivars' sysfs interface · 0f5b2c69
      Ard Biesheuvel 提交于
      Commit 5d9db883 ("efi: Add support for a UEFI variable filesystem")
      dated Oct 5, 2012, introduced a new efivarfs pseudo-filesystem to
      replace the efivars sysfs interface that was used up to that point to
      expose EFI variables to user space.
      
      The main problem with the sysfs interface was that it only supported up
      to 1024 bytes of payload per file, whereas the underlying variables
      themselves are only bounded by a platform specific per-variable and
      global limit that is typically much higher than 1024 bytes.
      
      The deprecated sysfs interface is only enabled on x86 and Itanium, other
      EFI enabled architectures only support the efivarfs pseudo-filesystem.
      
      So let's finally rip off the band aid, and drop the old interface
      entirely. This will make it easier to refactor and clean up the
      underlying infrastructure that is shared between efivars, efivarfs and
      efi-pstore, and is long overdue for a makeover.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      0f5b2c69
    • A
      efi: pstore: Omit efivars caching EFI varstore access layer · 85974825
      Ard Biesheuvel 提交于
      Avoid the efivars layer and simply call the newly introduced EFI
      varstore helpers instead. This simplifies the code substantially, and
      also allows us to remove some hacks in the shared efivars layer that
      were added for efi-pstore specifically.
      
      In order to be able to delete the EFI variable associated with a record,
      store the UTF-16 name of the variable in the pstore record's priv field.
      That way, we don't have to make guesses regarding which variable the
      record may have been loaded from.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      85974825
    • A
      efi: vars: Add thin wrapper around EFI get/set variable interface · 472831d4
      Ard Biesheuvel 提交于
      The current efivars layer is a jumble of list iterators, shadow data
      structures and safe variable manipulation helpers that really belong in
      the efivarfs pseudo file system once the obsolete sysfs access method to
      EFI variables is removed.
      
      So split off a minimal efivar get/set variable API that reuses the
      existing efivars_lock semaphore to mediate access to the various runtime
      services, primarily to ensure that performing a SetVariable() on one CPU
      while another is calling GetNextVariable() in a loop to enumerate the
      contents of the EFI variable store does not result in surprises.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      472831d4
    • A
      efi: vars: Don't drop lock in the middle of efivar_init() · ec3507b2
      Ard Biesheuvel 提交于
      Even though the efivars_lock lock is documented as protecting the
      efivars->ops pointer (among other things), efivar_init() happily
      releases and reacquires the lock for every EFI variable that it
      enumerates. This used to be needed because the lock was originally a
      spinlock, which prevented the callback that is invoked for every
      variable from being able to sleep. However, releasing the lock could
      potentially invalidate the ops pointer, but more importantly, it might
      allow a SetVariable() runtime service call to take place concurrently,
      and the UEFI spec does not define how this affects an enumeration that
      is running in parallel using the GetNextVariable() runtime service,
      which is what efivar_init() uses.
      
      In the meantime, the lock has been converted into a semaphore, and the
      only reason we need to drop the lock is because the efivarfs pseudo
      filesystem driver will otherwise deadlock when it invokes the efivars
      API from the callback to create the efivar_entry items and insert them
      into the linked list. (EFI pstore is affected in a similar way)
      
      So let's switch to helpers that can be used while the lock is already
      taken. This way, we can hold on to the lock throughout the enumeration.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      ec3507b2
  4. 15 6月, 2022 1 次提交
  5. 19 5月, 2022 1 次提交
  6. 03 5月, 2022 2 次提交
  7. 14 4月, 2022 2 次提交
  8. 07 4月, 2022 1 次提交
    • B
      x86/boot: Add Confidential Computing type to setup_data · 5ea98e01
      Brijesh Singh 提交于
      While launching encrypted guests, the hypervisor may need to provide
      some additional information during the guest boot. When booting under an
      EFI-based BIOS, the EFI configuration table contains an entry for the
      confidential computing blob that contains the required information.
      
      To support booting encrypted guests on non-EFI VMs, the hypervisor
      needs to pass this additional information to the guest kernel using a
      different method.
      
      For this purpose, introduce SETUP_CC_BLOB type in setup_data to hold
      the physical address of the confidential computing blob location. The
      boot loader or hypervisor may choose to use this method instead of an
      EFI configuration table. The CC blob location scanning should give
      preference to a setup_data blob over an EFI configuration table.
      
      In AMD SEV-SNP, the CC blob contains the address of the secrets and
      CPUID pages. The secrets page includes information such as a VM to PSP
      communication key and the CPUID page contains PSP-filtered CPUID values.
      Define the AMD SEV confidential computing blob structure.
      
      While at it, define the EFI GUID for the confidential computing blob.
      
        [ bp: Massage commit message, mark struct __packed. ]
      Signed-off-by: NBrijesh Singh <brijesh.singh@amd.com>
      Signed-off-by: NBorislav Petkov <bp@suse.de>
      Acked-by: NArd Biesheuvel <ardb@kernel.org>
      Link: https://lore.kernel.org/r/20220307213356.2797205-30-brijesh.singh@amd.com
      5ea98e01
  9. 05 3月, 2022 1 次提交
  10. 28 12月, 2021 1 次提交
    • C
      efi: Introduce EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER and corresponding structures · 1882de7f
      Chen Yu 提交于
      Platform Firmware Runtime Update image starts with UEFI headers, and the
      headers are defined in UEFI specification, but some of them have not been
      defined in the kernel yet.
      
      For example, the header layout of a capsule file looks like this:
      
      EFI_CAPSULE_HEADER
      EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER
      EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER
      EFI_FIRMWARE_IMAGE_AUTHENTICATION
      
      These structures would be used by the Platform Firmware Runtime Update
      driver to parse the format of capsule file to verify if the corresponding
      version number is valid. In this way, if the user provides an invalid
      capsule image, the kernel could be used as a guard to reject it, without
      switching to the Management Mode (which might be costly).
      
      EFI_CAPSULE_HEADER has been defined in the kernel, but the other
      structures have not been defined yet, so do that. Besides,
      EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER and
      EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER are required to be packed
      in the uefi specification. For this reason, use the __packed attribute
      to indicate to the compiler that the entire structure can appear
      misaligned in memory (as suggested by Ard) in case one of them follows
      the other directly in a capsule header.
      Acked-by: NArd Biesheuvel <ardb@kernel.org>
      Signed-off-by: NChen Yu <yu.c.chen@intel.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      1882de7f
  11. 13 12月, 2021 1 次提交
  12. 22 11月, 2021 1 次提交
  13. 11 11月, 2021 1 次提交
  14. 19 3月, 2021 1 次提交
    • A
      efi: use 32-bit alignment for efi_guid_t literals · fb98cc0b
      Ard Biesheuvel 提交于
      Commit 494c704f ("efi: Use 32-bit alignment for efi_guid_t") updated
      the type definition of efi_guid_t to ensure that it always appears
      sufficiently aligned (the UEFI spec is ambiguous about this, but given
      the fact that its EFI_GUID type is defined in terms of a struct carrying
      a uint32_t, the natural alignment is definitely >= 32 bits).
      
      However, we missed the EFI_GUID() macro which is used to instantiate
      efi_guid_t literals: that macro is still based on the guid_t type,
      which does not have a minimum alignment at all. This results in warnings
      such as
      
        In file included from drivers/firmware/efi/mokvar-table.c:35:
        include/linux/efi.h:1093:34: warning: passing 1-byte aligned argument to
            4-byte aligned parameter 2 of 'get_var' may result in an unaligned pointer
            access [-Walign-mismatch]
                status = get_var(L"SecureBoot", &EFI_GLOBAL_VARIABLE_GUID, NULL, &size,
                                                ^
        include/linux/efi.h:1101:24: warning: passing 1-byte aligned argument to
            4-byte aligned parameter 2 of 'get_var' may result in an unaligned pointer
            access [-Walign-mismatch]
                get_var(L"SetupMode", &EFI_GLOBAL_VARIABLE_GUID, NULL, &size, &setupmode);
      
      The distinction only matters on CPUs that do not support misaligned loads
      fully, but 32-bit ARM's load-multiple instructions fall into that category,
      and these are likely to be emitted by the compiler that built the firmware
      for loading word-aligned 128-bit GUIDs from memory
      
      So re-implement the initializer in terms of our own efi_guid_t type, so that
      the alignment becomes a property of the literal's type.
      
      Fixes: 494c704f ("efi: Use 32-bit alignment for efi_guid_t")
      Reported-by: NNathan Chancellor <nathan@kernel.org>
      Reviewed-by: NNick Desaulniers <ndesaulniers@google.com>
      Reviewed-by: NNathan Chancellor <nathan@kernel.org>
      Tested-by: NNathan Chancellor <nathan@kernel.org>
      Link: https://github.com/ClangBuiltLinux/linux/issues/1327Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      fb98cc0b
  15. 20 1月, 2021 2 次提交
  16. 18 1月, 2021 1 次提交
  17. 14 12月, 2020 1 次提交
    • A
      efi: ia64: disable the capsule loader · e0a6aa30
      Ard Biesheuvel 提交于
      EFI capsule loading is a feature that was introduced into EFI long after
      its initial introduction on Itanium, and it is highly unlikely that IA64
      systems are receiving firmware updates in the first place, let alone
      using EFI capsules.
      
      So let's disable capsule support altogether on IA64. This fixes a build
      error on IA64 due to a recent change that added an unconditional
      include of asm/efi.h, which IA64 does not provide.
      
      While at it, tweak the make rules a bit so that the EFI capsule
      component that is always builtin (even if the EFI capsule loader itself
      is built as a module) is omitted for all architectures if the module is
      not enabled in the build.
      
      Cc: Tony Luck <tony.luck@intel.com>
      Link: https://lore.kernel.org/linux-efi/20201214152200.38353-1-ardb@kernel.orgSigned-off-by: NArd Biesheuvel <ardb@kernel.org>
      e0a6aa30
  18. 05 11月, 2020 1 次提交
  19. 30 9月, 2020 3 次提交
    • A
      efi: efivars: un-export efivars_sysfs_init() · 5d3c8617
      Ard Biesheuvel 提交于
      efivars_sysfs_init() is only used locally in the source file that
      defines it, so make it static and unexport it.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      5d3c8617
    • A
      efi: pstore: move workqueue handling out of efivars · c9b51a2d
      Ard Biesheuvel 提交于
      The worker thread that gets kicked off to sync the state of the
      EFI variable list is only used by the EFI pstore implementation,
      and is defined in its source file. So let's move its scheduling
      there as well. Since our efivar_init() scan will bail on duplicate
      entries, there is no need to disable the workqueue like we did
      before, so we can run it unconditionally.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      c9b51a2d
    • A
      efi: pstore: disentangle from deprecated efivars module · 232f4eb6
      Ard Biesheuvel 提交于
      The EFI pstore implementation relies on the 'efivars' abstraction,
      which encapsulates the EFI variable store in a way that can be
      overridden by other backing stores, like the Google SMI one.
      
      On top of that, the EFI pstore implementation also relies on the
      efivars.ko module, which is a separate layer built on top of the
      'efivars' abstraction that exposes the [deprecated] sysfs entries
      for each variable that exists in the backing store.
      
      Since the efivars.ko module is deprecated, and all users appear to
      have moved to the efivarfs file system instead, let's prepare for
      its removal, by removing EFI pstore's dependency on it.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      232f4eb6
  20. 26 9月, 2020 1 次提交
  21. 16 9月, 2020 1 次提交
    • L
      efi: Support for MOK variable config table · 58c90902
      Lenny Szubowicz 提交于
      Because of system-specific EFI firmware limitations, EFI volatile
      variables may not be capable of holding the required contents of
      the Machine Owner Key (MOK) certificate store when the certificate
      list grows above some size. Therefore, an EFI boot loader may pass
      the MOK certs via a EFI configuration table created specifically for
      this purpose to avoid this firmware limitation.
      
      An EFI configuration table is a much more primitive mechanism
      compared to EFI variables and is well suited for one-way passage
      of static information from a pre-OS environment to the kernel.
      
      This patch adds initial kernel support to recognize, parse,
      and validate the EFI MOK configuration table, where named
      entries contain the same data that would otherwise be provided
      in similarly named EFI variables.
      
      Additionally, this patch creates a sysfs binary file for each
      EFI MOK configuration table entry found. These files are read-only
      to root and are provided for use by user space utilities such as
      mokutil.
      
      A subsequent patch will load MOK certs into the trusted platform
      key ring using this infrastructure.
      Signed-off-by: NLenny Szubowicz <lszubowi@redhat.com>
      Link: https://lore.kernel.org/r/20200905013107.10457-2-lszubowi@redhat.comSigned-off-by: NArd Biesheuvel <ardb@kernel.org>
      58c90902
  22. 08 8月, 2020 1 次提交
  23. 09 7月, 2020 1 次提交
    • A
      efi/efivars: Expose RT service availability via efivars abstraction · f88814cc
      Ard Biesheuvel 提交于
      Commit
      
        bf67fad1 ("efi: Use more granular check for availability for variable services")
      
      introduced a check into the efivarfs, efi-pstore and other drivers that
      aborts loading of the module if not all three variable runtime services
      (GetVariable, SetVariable and GetNextVariable) are supported. However, this
      results in efivarfs being unavailable entirely if only SetVariable support
      is missing, which is only needed if you want to make any modifications.
      Also, efi-pstore and the sysfs EFI variable interface could be backed by
      another implementation of the 'efivars' abstraction, in which case it is
      completely irrelevant which services are supported by the EFI firmware.
      
      So make the generic 'efivars' abstraction dependent on the availibility of
      the GetVariable and GetNextVariable EFI runtime services, and add a helper
      'efivar_supports_writes()' to find out whether the currently active efivars
      abstraction supports writes (and wire it up to the availability of
      SetVariable for the generic one).
      
      Then, use the efivar_supports_writes() helper to decide whether to permit
      efivarfs to be mounted read-write, and whether to enable efi-pstore or the
      sysfs EFI variable interface altogether.
      
      Fixes: bf67fad1 ("efi: Use more granular check for availability for variable services")
      Reported-by: NHeinrich Schuchardt <xypron.glpk@gmx.de>
      Acked-by: NIlias Apalodimas <ilias.apalodimas@linaro.org>
      Tested-by: NIlias Apalodimas <ilias.apalodimas@linaro.org>
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      f88814cc
  24. 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
  25. 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
  26. 21 5月, 2020 2 次提交
  27. 17 5月, 2020 1 次提交