1. 24 2月, 2020 40 次提交
    • A
      efi: Use more granular check for availability for variable services · bf67fad1
      Ard Biesheuvel 提交于
      The UEFI spec rev 2.8 permits firmware implementations to support only
      a subset of EFI runtime services at OS runtime (i.e., after the call to
      ExitBootServices()), so let's take this into account in the drivers that
      rely specifically on the availability of the EFI variable services.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      bf67fad1
    • 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: Rewrite FDT param discovery routines · e457ed51
      Ard Biesheuvel 提交于
      The efi_get_fdt_params() routine uses the early OF device tree
      traversal helpers, that iterate over each node in the DT and invoke
      a caller provided callback that can inspect the node's contents and
      look for the required data. This requires a special param struct to
      be passed around, with pointers into param enumeration structs that
      contain (and duplicate) property names and offsets into yet another
      struct that carries the collected data.
      
      Since we know the data we look for is either under /hypervisor/uefi
      or under /chosen, it is much simpler to use the libfdt routines, and
      just try to grab a reference to either node directly, and read each
      property in sequence.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      e457ed51
    • 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/arm: Move FDT param discovery code out of efi.c · ac5abc70
      Ard Biesheuvel 提交于
      On ARM systems, we discover the UEFI system table address and memory
      map address from the /chosen node in the device tree, or in the Xen
      case, from a similar node under /hypervisor.
      
      Before making some functional changes to that code, move it into its
      own file that only gets built if CONFIG_EFI_PARAMS_FROM_FDT=y.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      ac5abc70
    • A
      efi/x86: Add true mixed mode entry point into .compat section · 97aa2765
      Ard Biesheuvel 提交于
      Currently, mixed mode is closely tied to the EFI handover protocol
      and relies on intimate knowledge of the bootparams structure, setup
      header etc, all of which are rather byzantine and entirely specific
      to x86.
      
      Even though no other EFI supported architectures are currently known
      that could support something like mixed mode, it still makes sense to
      abstract a bit from this, and make it part of a generic Linux on EFI
      boot protocol.
      
      To that end, add a .compat section to the mixed mode binary, and populate
      it with the PE machine type and entry point address, allowing firmware
      implementations to match it to their native machine type, and invoke
      non-native binaries using a secondary entry point.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      97aa2765
    • 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/x86: Drop redundant .bss section · 832187f0
      Ard Biesheuvel 提交于
      In commit
      
        c7fb93ec ("x86/efi: Include a .bss section within the PE/COFF headers")
      
      we added a separate .bss section to the PE/COFF header of the compressed
      kernel describing the static memory footprint of the decompressor, to
      ensure that it has enough headroom to decompress itself.
      
      We can achieve the exact same result by increasing the virtual size of
      the .text section, without changing the raw size, which, as per the
      PE/COFF specification, requires the loader to zero initialize the delta.
      
      Doing so frees up a slot in the section table, which we will use later
      to describe the mixed mode entrypoint.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      832187f0
    • A
      efi/x86: add headroom to decompressor BSS to account for setup block · 223e3ee5
      Ard Biesheuvel 提交于
      In the bootparams struct, init_size defines the static footprint of the
      bzImage, counted from the start of the kernel image, i.e., startup_32().
      
      The PE/COFF metadata declares the same size for the entire image, but this
      time, the image includes the setup block as well, and so the space reserved
      by UEFI is a bit too small. This usually doesn't matter, since we normally
      relocate the kernel into a memory allocation of the correct size.
      But in the unlikely case that the image happens to be loaded at exactly
      the preferred offset, we skip this relocation, and execute the image in
      place, stepping on memory beyond the provided allocation, which may be
      in use for other purposes.
      
      Let's fix this by adding the size of the setup block to the image size as
      declared in the PE/COFF header.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      223e3ee5
    • 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/arm: Drop unnecessary references to efi.systab · 8819ba39
      Ard Biesheuvel 提交于
      Instead of populating efi.systab very early during efi_init() with
      a mapping that is released again before the function exits, use a
      local variable here. Now that we use efi.runtime to access the runtime
      services table, this removes the only reference efi.systab, so there is
      no need to populate it anymore, or discover its virtually remapped
      address. So drop the references entirely.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      8819ba39
    • 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: Merge assignments of efi.runtime_version · 09308012
      Ard Biesheuvel 提交于
      efi.runtime_version is always set to the same value on both
      existing code paths, so just set it earlier from a shared one.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      09308012
    • 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/x86: Remove runtime table address from kexec EFI setup data · 0a67361d
      Ard Biesheuvel 提交于
      Since commit 33b85447 ("efi/x86: Drop two near identical versions
      of efi_runtime_init()"), we no longer map the EFI runtime services table
      before calling SetVirtualAddressMap(), which means we don't need the 1:1
      mapped physical address of this table, and so there is no point in passing
      the address via EFI setup data on kexec boot.
      
      Note that the kexec tools will still look for this address in sysfs, so
      we still need to provide it.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      0a67361d
    • 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/ia64: Switch to efi_config_parse_tables() · 68631292
      Ard Biesheuvel 提交于
      IA64 calls efi_config_parse_tables() via efi_config_init(), which
      does an explicit memremap() of the tables, which is unnecessary
      on IA64. So let's call efi_config_parse_tables() directly, passing
      the __va() of the config table array.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      68631292
    • A
      efi/ia64: Use local variable for EFI system table address · beaf1c74
      Ard Biesheuvel 提交于
      The IA64 code never refers to the EFI system table except from
      inside the scope of efi_init(). So let's use a local variable
      instead of efi.systab, which will be going away soon.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      beaf1c74
    • A
      efi/ia64: Use existing helpers to locate ESI table · c0019f57
      Ard Biesheuvel 提交于
      Instead of iterating over the EFI config table array manually,
      declare it as an arch table so it gets picked up by the existing
      config table handling code.
      
      Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      c0019f57
    • 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: 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/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/x86: Replace #ifdefs with IS_ENABLED() checks · a570b062
      Ard Biesheuvel 提交于
      When possible, IS_ENABLED() conditionals are preferred over #ifdefs,
      given that the latter hide the code from the compiler entirely, which
      reduces build test coverage when the option is not enabled.
      
      So replace an instance in the x86 efi startup code.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      a570b062
    • A
      efi/x86: Reindent struct initializer for legibility · 14b60cc8
      Ard Biesheuvel 提交于
      Reindent the efi_memory_map_data initializer so that all the = signs
      are aligned vertically, making the resulting code much easier to read.
      Suggested-by: NIngo Molnar <mingo@kernel.org>
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      14b60cc8
    • H
      efi/capsule-loader: Drop superfluous assignment · e0dc26c7
      Heinrich Schuchardt 提交于
      In efi_capsule_write() the value 0 assigned to ret is never used.
      
      Identified with cppcheck.
      Signed-off-by: NHeinrich Schuchardt <xypron.glpk@gmx.de>
      Link: https://lore.kernel.org/r/20200223205435.114915-1-xypron.glpk@gmx.deSigned-off-by: NArd Biesheuvel <ardb@kernel.org>
      e0dc26c7
    • H
      efi/esrt: Clean up efi_esrt_init · 6d2576e4
      Heinrich Schuchardt 提交于
      Remove an unused variable in __init efi_esrt_init().
      Simplify a logical constraint.
      Signed-off-by: NHeinrich Schuchardt <xypron.glpk@gmx.de>
      Link: https://lore.kernel.org/r/20200223204557.114634-1-xypron.glpk@gmx.deSigned-off-by: NArd Biesheuvel <ardb@kernel.org>
      6d2576e4
    • H
      f01dd5b3
    • H
      efi/libstub: Describe RNG functions · ba832f68
      Heinrich Schuchardt 提交于
      Provide descriptions for the functions invoking the EFI_RNG_PROTOCOL.
      Signed-off-by: NHeinrich Schuchardt <xypron.glpk@gmx.de>
      Reviewed-by: NDominik Brodowski <linux@dominikbrodowski.net>
      Link: https://lore.kernel.org/r/20200221114716.4372-1-xypron.glpk@gmx.deSigned-off-by: NArd Biesheuvel <ardb@kernel.org>
      ba832f68
    • H
      efi/libstub: Describe efi_relocate_kernel() · 0255973b
      Heinrich Schuchardt 提交于
      Update the description of of efi_relocate_kernel() to match Sphinx style.
      
      Update parameter references in the description of other memory functions
      to use @param style.
      Signed-off-by: NHeinrich Schuchardt <xypron.glpk@gmx.de>
      Acked-by: NRandy Dunlap <rdunlap@infradead.org>
      Link: https://lore.kernel.org/r/20200220065317.9096-1-xypron.glpk@gmx.deSigned-off-by: NArd Biesheuvel <ardb@kernel.org>
      0255973b