1. 02 2月, 2017 1 次提交
    • A
      efi/fdt: Avoid FDT manipulation after ExitBootServices() · c8f325a5
      Ard Biesheuvel 提交于
      Some AArch64 UEFI implementations disable the MMU in ExitBootServices(),
      after which unaligned accesses to RAM are no longer supported.
      
      Commit:
      
        abfb7b68 ("efi/libstub/arm*: Pass latest memory map to the kernel")
      
      fixed an issue in the memory map handling of the stub FDT code, but
      inadvertently created an issue with such firmware, by moving some
      of the FDT manipulation to after the invocation of ExitBootServices().
      
      Given that the stub's libfdt implementation uses the ordinary, accelerated
      string functions, which rely on hardware handling of unaligned accesses,
      manipulating the FDT with the MMU off may result in alignment faults.
      
      So fix the situation by moving the update_fdt_memmap() call into the
      callback function invoked by efi_exit_boot_services() right before it
      calls the ExitBootServices() UEFI service (which is arguably a better
      place for it anyway)
      
      Note that disabling the MMU in ExitBootServices() is not compliant with
      the UEFI spec, and carries great risk due to the fact that switching from
      cached to uncached memory accesses halfway through compiler generated code
      (i.e., involving a stack) can never be done in a way that is architecturally
      safe.
      
      Fixes: abfb7b68 ("efi/libstub/arm*: Pass latest memory map to the kernel")
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Tested-by: NRiku Voipio <riku.voipio@linaro.org>
      Cc: <stable@vger.kernel.org>
      Cc: mark.rutland@arm.com
      Cc: linux-efi@vger.kernel.org
      Cc: matt@codeblueprint.co.uk
      Cc: leif.lindholm@linaro.org
      Cc: linux-arm-kernel@lists.infradead.org
      Link: http://lkml.kernel.org/r/1485971102-23330-2-git-send-email-ard.biesheuvel@linaro.orgSigned-off-by: NIngo Molnar <mingo@kernel.org>
      c8f325a5
  2. 01 2月, 2017 6 次提交
  3. 07 1月, 2017 1 次提交
    • N
      x86/efi: Don't allocate memmap through memblock after mm_init() · 20b1e22d
      Nicolai Stange 提交于
      With the following commit:
      
        4bc9f92e ("x86/efi-bgrt: Use efi_mem_reserve() to avoid copying image data")
      
      ...  efi_bgrt_init() calls into the memblock allocator through
      efi_mem_reserve() => efi_arch_mem_reserve() *after* mm_init() has been called.
      
      Indeed, KASAN reports a bad read access later on in efi_free_boot_services():
      
        BUG: KASAN: use-after-free in efi_free_boot_services+0xae/0x24c
                  at addr ffff88022de12740
        Read of size 4 by task swapper/0/0
        page:ffffea0008b78480 count:0 mapcount:-127
        mapping:          (null) index:0x1 flags: 0x5fff8000000000()
        [...]
        Call Trace:
         dump_stack+0x68/0x9f
         kasan_report_error+0x4c8/0x500
         kasan_report+0x58/0x60
         __asan_load4+0x61/0x80
         efi_free_boot_services+0xae/0x24c
         start_kernel+0x527/0x562
         x86_64_start_reservations+0x24/0x26
         x86_64_start_kernel+0x157/0x17a
         start_cpu+0x5/0x14
      
      The instruction at the given address is the first read from the memmap's
      memory, i.e. the read of md->type in efi_free_boot_services().
      
      Note that the writes earlier in efi_arch_mem_reserve() don't splat because
      they're done through early_memremap()ed addresses.
      
      So, after memblock is gone, allocations should be done through the "normal"
      page allocator. Introduce a helper, efi_memmap_alloc() for this. Use
      it from efi_arch_mem_reserve(), efi_free_boot_services() and, for the sake
      of consistency, from efi_fake_memmap() as well.
      
      Note that for the latter, the memmap allocations cease to be page aligned.
      This isn't needed though.
      Tested-by: NDan Williams <dan.j.williams@intel.com>
      Signed-off-by: NNicolai Stange <nicstange@gmail.com>
      Reviewed-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: <stable@vger.kernel.org> # v4.9
      Cc: Dave Young <dyoung@redhat.com>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Matt Fleming <matt@codeblueprint.co.uk>
      Cc: Mika Penttilä <mika.penttila@nextfour.com>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-efi@vger.kernel.org
      Fixes: 4bc9f92e ("x86/efi-bgrt: Use efi_mem_reserve() to avoid copying image data")
      Link: http://lkml.kernel.org/r/20170105125130.2815-1-nicstange@gmail.comSigned-off-by: NIngo Molnar <mingo@kernel.org>
      20b1e22d
  4. 28 12月, 2016 1 次提交
  5. 14 12月, 2016 1 次提交
    • P
      Remove references to dead make variable LINUX_INCLUDE · 846221cf
      Paul Bolle 提交于
      Commit 4fd06960 ("Use the new x86 setup code for i386") introduced a
      reference to the make variable LINUX_INCLUDE. That reference got moved
      around a bit and copied twice and now there are three references to it.
      
      There has never been a definition of that variable. (Presumably that is
      because it started out as a mistyped reference to LINUXINCLUDE.) So this
      reference has always been an empty string. Let's remove it before it
      spreads any further.
      Signed-off-by: NPaul Bolle <pebolle@tiscali.nl>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      846221cf
  6. 25 11月, 2016 1 次提交
    • A
      efi/libstub: Make efi_random_alloc() allocate below 4 GB on 32-bit · 018edcfa
      Ard Biesheuvel 提交于
      The UEFI stub executes in the context of the firmware, which identity
      maps the available system RAM, which implies that only memory below
      4 GB can be used for allocations on 32-bit architectures, even on [L]PAE
      capable hardware.
      
      So ignore any reported memory above 4 GB in efi_random_alloc(). This
      also fixes a reported build problem on ARM under -Os, where the 64-bit
      logical shift relies on a software routine that the ARM decompressor does
      not provide.
      
      A second [minor] issue is also fixed, where the '+ 1' is moved out of
      the shift, where it belongs: the reason for its presence is that a
      memory region where start == end should count as a single slot, given
      that 'end' takes the desired size and alignment of the allocation into
      account.
      
      To clarify the code in this regard, rename start/end to 'first_slot' and
      'last_slot', respectively, and introduce 'region_end' to describe the
      last usable address of the current region.
      Reported-by: NArnd Bergmann <arnd@arndb.de>
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Matt Fleming <matt@codeblueprint.co.uk>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-efi@vger.kernel.org
      Link: http://lkml.kernel.org/r/1480010543-25709-2-git-send-email-ard.biesheuvel@linaro.orgSigned-off-by: NIngo Molnar <mingo@kernel.org>
      018edcfa
  7. 13 11月, 2016 6 次提交
    • L
      x86/efi: Retrieve and assign Apple device properties · 58c5475a
      Lukas Wunner 提交于
      Apple's EFI drivers supply device properties which are needed to support
      Macs optimally. They contain vital information which cannot be obtained
      any other way (e.g. Thunderbolt Device ROM). They're also used to convey
      the current device state so that OS drivers can pick up where EFI
      drivers left (e.g. GPU mode setting).
      
      There's an EFI driver dubbed "AAPL,PathProperties" which implements a
      per-device key/value store. Other EFI drivers populate it using a custom
      protocol. The macOS bootloader /System/Library/CoreServices/boot.efi
      retrieves the properties with the same protocol. The kernel extension
      AppleACPIPlatform.kext subsequently merges them into the I/O Kit
      registry (see ioreg(8)) where they can be queried by other kernel
      extensions and user space.
      
      This commit extends the efistub to retrieve the device properties before
      ExitBootServices is called. It assigns them to devices in an fs_initcall
      so that they can be queried with the API in <linux/property.h>.
      
      Note that the device properties will only be available if the kernel is
      booted with the efistub. Distros should adjust their installers to
      always use the efistub on Macs. grub with the "linux" directive will not
      work unless the functionality of this commit is duplicated in grub.
      (The "linuxefi" directive should work but is not included upstream as of
      this writing.)
      
      The custom protocol has GUID 91BD12FE-F6C3-44FB-A5B7-5122AB303AE0 and
      looks like this:
      
      typedef struct {
      	unsigned long version; /* 0x10000 */
      	efi_status_t (*get) (
      		IN	struct apple_properties_protocol *this,
      		IN	struct efi_dev_path *device,
      		IN	efi_char16_t *property_name,
      		OUT	void *buffer,
      		IN OUT	u32 *buffer_len);
      		/* EFI_SUCCESS, EFI_NOT_FOUND, EFI_BUFFER_TOO_SMALL */
      	efi_status_t (*set) (
      		IN	struct apple_properties_protocol *this,
      		IN	struct efi_dev_path *device,
      		IN	efi_char16_t *property_name,
      		IN	void *property_value,
      		IN	u32 property_value_len);
      		/* allocates copies of property name and value */
      		/* EFI_SUCCESS, EFI_OUT_OF_RESOURCES */
      	efi_status_t (*del) (
      		IN	struct apple_properties_protocol *this,
      		IN	struct efi_dev_path *device,
      		IN	efi_char16_t *property_name);
      		/* EFI_SUCCESS, EFI_NOT_FOUND */
      	efi_status_t (*get_all) (
      		IN	struct apple_properties_protocol *this,
      		OUT	void *buffer,
      		IN OUT	u32 *buffer_len);
      		/* EFI_SUCCESS, EFI_BUFFER_TOO_SMALL */
      } apple_properties_protocol;
      
      Thanks to Pedro Vilaça for this blog post which was helpful in reverse
      engineering Apple's EFI drivers and bootloader:
      https://reverse.put.as/2016/06/25/apple-efi-firmware-passwords-and-the-scbo-myth/
      
      If someone at Apple is reading this, please note there's a memory leak
      in your implementation of the del() function as the property struct is
      freed but the name and value allocations are not.
      
      Neither the macOS bootloader nor Apple's EFI drivers check the protocol
      version, but we do to avoid breakage if it's ever changed. It's been the
      same since at least OS X 10.6 (2009).
      
      The get_all() function conveniently fills a buffer with all properties
      in marshalled form which can be passed to the kernel as a setup_data
      payload. The number of device properties is dynamic and can change
      between a first invocation of get_all() (to determine the buffer size)
      and a second invocation (to retrieve the actual buffer), hence the
      peculiar loop which does not finish until the buffer size settles.
      The macOS bootloader does the same.
      
      The setup_data payload is later on unmarshalled in an fs_initcall. The
      idea is that most buses instantiate devices in "subsys" initcall level
      and drivers are usually bound to these devices in "device" initcall
      level, so we assign the properties in-between, i.e. in "fs" initcall
      level.
      
      This assumes that devices to which properties pertain are instantiated
      from a "subsys" initcall or earlier. That should always be the case
      since on macOS, AppleACPIPlatformExpert::matchEFIDevicePath() only
      supports ACPI and PCI nodes and we've fully scanned those buses during
      "subsys" initcall level.
      
      The second assumption is that properties are only needed from a "device"
      initcall or later. Seems reasonable to me, but should this ever not work
      out, an alternative approach would be to store the property sets e.g. in
      a btree early during boot. Then whenever device_add() is called, an EFI
      Device Path would have to be constructed for the newly added device,
      and looked up in the btree. That way, the property set could be assigned
      to the device immediately on instantiation. And this would also work for
      devices instantiated in a deferred fashion. It seems like this approach
      would be more complicated and require more code. That doesn't seem
      justified without a specific use case.
      
      For comparison, the strategy on macOS is to assign properties to objects
      in the ACPI namespace (AppleACPIPlatformExpert::mergeEFIProperties()).
      That approach is definitely wrong as it fails for devices not present in
      the namespace: The NHI EFI driver supplies properties for attached
      Thunderbolt devices, yet on Macs with Thunderbolt 1 only one device
      level behind the host controller is described in the namespace.
      Consequently macOS cannot assign properties for chained devices. With
      Thunderbolt 2 they started to describe three device levels behind host
      controllers in the namespace but this grossly inflates the SSDT and
      still fails if the user daisy-chained more than three devices.
      
      We copy the property names and values from the setup_data payload to
      swappable virtual memory and afterwards make the payload available to
      the page allocator. This is just for the sake of good housekeeping, it
      wouldn't occupy a meaningful amount of physical memory (4444 bytes on my
      machine). Only the payload is freed, not the setup_data header since
      otherwise we'd break the list linkage and we cannot safely update the
      predecessor's ->next link because there's no locking for the list.
      
      The payload is currently not passed on to kexec'ed kernels, same for PCI
      ROMs retrieved by setup_efi_pci(). This can be added later if there is
      demand by amending setup_efi_state(). The payload can then no longer be
      made available to the page allocator of course.
      
      Tested-by: Lukas Wunner <lukas@wunner.de> [MacBookPro9,1]
      Tested-by: Pierre Moreau <pierre.morrow@free.fr> [MacBookPro11,3]
      Signed-off-by: NLukas Wunner <lukas@wunner.de>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      Cc: Andreas Noever <andreas.noever@gmail.com>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Pedro Vilaça <reverser@put.as>
      Cc: Peter Jones <pjones@redhat.com>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: grub-devel@gnu.org
      Cc: linux-efi@vger.kernel.org
      Link: http://lkml.kernel.org/r/20161112213237.8804-9-matt@codeblueprint.co.ukSigned-off-by: NIngo Molnar <mingo@kernel.org>
      58c5475a
    • L
      efi: Add device path parser · 46cd4b75
      Lukas Wunner 提交于
      We're about to extended the efistub to retrieve device properties from
      EFI on Apple Macs. The properties use EFI Device Paths to indicate the
      device they belong to. This commit adds a parser which, given an EFI
      Device Path, locates the corresponding struct device and returns a
      reference to it.
      
      Initially only ACPI and PCI Device Path nodes are supported, these are
      the only types needed for Apple device properties (the corresponding
      macOS function AppleACPIPlatformExpert::matchEFIDevicePath() does not
      support any others). Further node types can be added with little to
      moderate effort.
      
      Apple device properties is currently the only use case of this parser,
      but Peter Jones intends to use it to match up devices with the
      ConInDev/ConOutDev/ErrOutDev variables and add sysfs attributes to these
      devices to say the hardware supports using them as console. Thus,
      make this parser a separate component which can be selected with config
      option EFI_DEV_PATH_PARSER. It can in principle be compiled as a module
      if acpi_get_first_physical_node() and acpi_bus_type are exported (and
      efi_get_device_by_path() itself is exported).
      
      The dependency on CONFIG_ACPI is needed for acpi_match_device_ids().
      It can be removed if an empty inline stub is added for that function.
      Signed-off-by: NLukas Wunner <lukas@wunner.de>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      Cc: Andreas Noever <andreas.noever@gmail.com>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Peter Jones <pjones@redhat.com>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-efi@vger.kernel.org
      Link: http://lkml.kernel.org/r/20161112213237.8804-7-matt@codeblueprint.co.ukSigned-off-by: NIngo Molnar <mingo@kernel.org>
      46cd4b75
    • A
      efi/arm*/libstub: Invoke EFI_RNG_PROTOCOL to seed the UEFI RNG table · 568bc4e8
      Ard Biesheuvel 提交于
      Invoke the EFI_RNG_PROTOCOL protocol in the context of the stub and
      install the Linux-specific RNG seed UEFI config table. This will be
      picked up by the EFI routines in the core kernel to seed the kernel
      entropy pool.
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      Reviewed-by: NKees Cook <keescook@chromium.org>
      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: http://lkml.kernel.org/r/20161112213237.8804-6-matt@codeblueprint.co.ukSigned-off-by: NIngo Molnar <mingo@kernel.org>
      568bc4e8
    • A
      efi/libstub: Add random.c to ARM build · a6a14469
      Ard Biesheuvel 提交于
      Make random.c build for ARM by moving the fallback definition of
      EFI_ALLOC_ALIGN to efistub.h, and replacing a division by a value
      we know to be a power of 2 with a right shift (this is required since
      ARM does not have any integer division helper routines in its decompressor)
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      Reviewed-by: NKees Cook <keescook@chromium.org>
      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: http://lkml.kernel.org/r/20161112213237.8804-5-matt@codeblueprint.co.ukSigned-off-by: NIngo Molnar <mingo@kernel.org>
      a6a14469
    • A
      efi: Add support for seeding the RNG from a UEFI config table · 63625988
      Ard Biesheuvel 提交于
      Specify a Linux specific UEFI configuration table that carries some
      random bits, and use the contents during early boot to seed the kernel's
      random number generator. This allows much strong random numbers to be
      generated early on.
      
      The entropy is fed to the kernel using add_device_randomness(), which is
      documented as being appropriate for being called very early.
      
      Since UEFI configuration tables may also be consumed by kexec'd kernels,
      register a reboot notifier that updates the seed in the table.
      
      Note that the config table could be generated by the EFI stub or by any
      other UEFI driver or application (e.g., GRUB), but the random seed table
      GUID and the associated functionality should be considered an internal
      kernel interface (unless it is promoted to ABI later on)
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      Reviewed-by: NKees Cook <keescook@chromium.org>
      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: http://lkml.kernel.org/r/20161112213237.8804-4-matt@codeblueprint.co.ukSigned-off-by: NIngo Molnar <mingo@kernel.org>
      63625988
    • R
      efi/libstub: Fix allocation size calculations · 5b88a31c
      Roy Franz 提交于
      Adjust the size used in calculations to match the actual size of allocation
      that will be performed based on EFI size/alignment constraints.
      efi_high_alloc() and efi_low_alloc() use the passed size in bytes directly
      to find space in the memory map for the allocation, rather than the actual
      allocation size that has been adjusted for size and alignment constraints.
      This results in failed allocations and retries in efi_high_alloc().  The
      same error is present in efi_low_alloc(), although failure will only happen
      if the lowest memory block is small.
      Also use EFI_PAGE_SIZE consistently and remove use of EFI_PAGE_SHIFT to
      calculate page size.
      Signed-off-by: NRoy Franz <roy.franz@hpe.com>
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      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: http://lkml.kernel.org/r/20161112213237.8804-2-matt@codeblueprint.co.ukSigned-off-by: NIngo Molnar <mingo@kernel.org>
      5b88a31c
  8. 08 11月, 2016 1 次提交
  9. 19 10月, 2016 1 次提交
    • A
      efi/arm: Fix absolute relocation detection for older toolchains · b0dddf6c
      Ard Biesheuvel 提交于
      When building the ARM kernel with CONFIG_EFI=y, the following build
      error may occur when using a less recent version of binutils (2.23 or
      older):
      
         STUBCPY drivers/firmware/efi/libstub/lib-sort.stub.o
       00000000 R_ARM_ABS32       sort
       00000004 R_ARM_ABS32       __ksymtab_strings
       drivers/firmware/efi/libstub/lib-sort.stub.o: absolute symbol references not allowed in the EFI stub
      
      (and when building with debug symbols, the list above is much longer, and
      contains all the internal references between the .debug sections and the
      actual code)
      
      This issue is caused by the fact that objcopy v2.23 or earlier does not
      support wildcards in its -R and -j options, which means the following
      line from the Makefile:
      
        STUBCOPY_FLAGS-y		:= -R .debug* -R *ksymtab* -R *kcrctab*
      
      fails to take effect, leaving harmless absolute relocations in the binary
      that are indistinguishable from relocations that may cause crashes at
      runtime due to the fact that these relocations are resolved at link time
      using the virtual address of the kernel, which is always different from
      the address at which the EFI firmware loads and invokes the stub.
      
      So, as a workaround, disable debug symbols explicitly when building the
      stub for ARM, and strip the ksymtab and kcrctab symbols for the only
      exported symbol we currently reuse in the stub, which is 'sort'.
      Tested-by: NJon Hunter <jonathanh@nvidia.com>
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Reviewed-by: NMatt Fleming <matt@codeblueprint.co.uk>
      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: http://lkml.kernel.org/r/1476805991-7160-2-git-send-email-ard.biesheuvel@linaro.orgSigned-off-by: NIngo Molnar <mingo@kernel.org>
      b0dddf6c
  10. 18 10月, 2016 6 次提交
  11. 20 9月, 2016 1 次提交
    • M
      x86/efi: Round EFI memmap reservations to EFI_PAGE_SIZE · 92dc3350
      Matt Fleming 提交于
      Mike Galbraith reported that his machine started rebooting during boot
      after,
      
        commit 8e80632f ("efi/esrt: Use efi_mem_reserve() and avoid a kmalloc()")
      
      The ESRT table on his machine is 56 bytes and at no point in the
      efi_arch_mem_reserve() call path is that size rounded up to
      EFI_PAGE_SIZE, nor is the start address on an EFI_PAGE_SIZE boundary.
      
      Since the EFI memory map only deals with whole pages, inserting an EFI
      memory region with 56 bytes results in a new entry covering zero
      pages, and completely screws up the calculations for the old regions
      that were trimmed.
      
      Round all sizes upwards, and start addresses downwards, to the nearest
      EFI_PAGE_SIZE boundary.
      
      Additionally, efi_memmap_insert() expects the mem::range::end value to
      be one less than the end address for the region.
      Reported-by: NMike Galbraith <umgwanakikbuti@gmail.com>
      Reported-by: NMike Krinkin <krinkin.m.u@gmail.com>
      Tested-by: NMike Krinkin <krinkin.m.u@gmail.com>
      Cc: Peter Jones <pjones@redhat.com>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: Taku Izumi <izumi.taku@jp.fujitsu.com>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      92dc3350
  12. 09 9月, 2016 14 次提交
    • A
      efi/arm64: Treat regions with WT/WC set but WB cleared as memory · cb82cce7
      Ard Biesheuvel 提交于
      Currently, memory regions are only recorded in the memblock memory table
      if they have the EFI_MEMORY_WB memory type attribute set. In case the
      region is of a reserved type, it is also marked as MEMBLOCK_NOMAP, which
      will leave it out of the linear mapping.
      
      However, memory regions may legally have the EFI_MEMORY_WT or EFI_MEMORY_WC
      attributes set, and the EFI_MEMORY_WB cleared, in which case the region in
      question is obviously backed by normal memory, but is not recorded in the
      memblock memory table at all. Since it would be useful to be able to
      identify any UEFI reported memory region using memblock_is_memory(), it
      makes sense to add all memory to the memblock memory table, and simply mark
      it as MEMBLOCK_NOMAP if it lacks the EFI_MEMORY_WB attribute.
      
      While implementing this, let's refactor the code slightly to make it easier
      to understand: replace is_normal_ram() with is_memory(), and make it return
      true for each region that has any of the WB|WT|WC bits set. (This follows
      the AArch64 bindings in the UEFI spec, which state that those are the
      attributes that map to normal memory)
      
      Also, replace is_reserve_region() with is_usable_memory(), and only invoke
      it if the region in question was identified as memory by is_memory() in the
      first place. The net result is the same (only reserved regions that are
      backed by memory end up in the memblock memory table with the MEMBLOCK_NOMAP
      flag set) but carried out in a more straightforward way.
      
      Finally, we remove the trailing asterisk in the EFI debug output. Keeping it
      clutters the code, and it serves no real purpose now that we no longer
      temporarily reserve BootServices code and data regions like we did in the
      early days of EFI support on arm64 Linux (which it inherited from the x86
      implementation)
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Reviewed-by: NLeif Lindholm <leif.lindholm@linaro.org>
      Tested-by: NJames Morse <james.morse@arm.com>
      Reviewed-by: NJames Morse <james.morse@arm.com>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      cb82cce7
    • I
      efi: Add efi_test driver for exporting UEFI runtime service interfaces · ff6301da
      Ivan Hu 提交于
      This driver is used by the Firmware Test Suite (FWTS) for testing the UEFI
      runtime interfaces readiness of the firmware.
      
      This driver exports UEFI runtime service interfaces into userspace,
      which allows to use and test UEFI runtime services provided by the
      firmware.
      
      This driver uses the efi.<service> function pointers directly instead of
      going through the efivar API to allow for direct testing of the UEFI
      runtime service interfaces provided by the firmware.
      
      Details for FWTS are available from,
      <https://wiki.ubuntu.com/FirmwareTestSuite>
      Signed-off-by: NIvan Hu <ivan.hu@canonical.com>
      Cc: joeyli <jlee@suse.com>
      Cc: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      ff6301da
    • A
      efi/arm64: Add debugfs node to dump UEFI runtime page tables · 9d80448a
      Ard Biesheuvel 提交于
      Register the debugfs node 'efi_page_tables' to allow the UEFI runtime
      page tables to be inspected. Note that ARM does not have 'asm/ptdump.h'
      [yet] so for now, this is arm64 only.
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Acked-by: NMark Rutland <mark.rutland@arm.com>
      Cc: Leif Lindholm <leif.lindholm@linaro.org>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      9d80448a
    • A
      efi: Replace runtime services spinlock with semaphore · dce48e35
      Ard Biesheuvel 提交于
      The purpose of the efi_runtime_lock is to prevent concurrent calls into
      the firmware. There is no need to use spinlocks here, as long as we ensure
      that runtime service invocations from an atomic context (i.e., EFI pstore)
      cannot block.
      
      So use a semaphore instead, and use down_trylock() in the nonblocking case.
      We don't use a mutex here because the mutex_trylock() function must not
      be called from interrupt context, whereas the down_trylock() can.
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Leif Lindholm <leif.lindholm@linaro.org>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: Sylvain Chouleur <sylvain.chouleur@gmail.com>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      dce48e35
    • S
      efi: Don't use spinlocks for efi vars · 21b3ddd3
      Sylvain Chouleur 提交于
      All efivars operations are protected by a spinlock which prevents
      interruptions and preemption. This is too restricted, we just need a
      lock preventing concurrency.
      The idea is to use a semaphore of count 1 and to have two ways of
      locking, depending on the context:
      - In interrupt context, we call down_trylock(), if it fails we return
        an error
      - In normal context, we call down_interruptible()
      
      We don't use a mutex here because the mutex_trylock() function must not
      be called from interrupt context, whereas the down_trylock() can.
      Signed-off-by: NSylvain Chouleur <sylvain.chouleur@intel.com>
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Leif Lindholm <leif.lindholm@linaro.org>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: Sylvain Chouleur <sylvain.chouleur@gmail.com>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      21b3ddd3
    • S
      efi: Use a file local lock for efivars · 217b27d4
      Sylvain Chouleur 提交于
      This patch replaces the spinlock in the efivars struct with a single lock
      for the whole vars.c file.  The goal of this lock is to protect concurrent
      calls to efi variable services, registering and unregistering. This allows
      us to register new efivars operations without having in-progress call.
      Signed-off-by: NSylvain Chouleur <sylvain.chouleur@intel.com>
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Leif Lindholm <leif.lindholm@linaro.org>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: Sylvain Chouleur <sylvain.chouleur@gmail.com>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      217b27d4
    • A
      efi/arm*: esrt: Add missing call to efi_esrt_init() · 2ead3084
      Ard Biesheuvel 提交于
      ESRT support is built by default for all architectures that define
      CONFIG_EFI. However, this support was not wired up yet for ARM/arm64,
      since efi_esrt_init() was never called. So add the missing call.
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Leif Lindholm <leif.lindholm@linaro.org>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: Peter Jones <pjones@redhat.com>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      2ead3084
    • A
      efi/esrt: Use memremap not ioremap to access ESRT table in memory · f58a37b2
      Ard Biesheuvel 提交于
      On ARM and arm64, ioremap() and memremap() are not interchangeable like
      on x86, and the use of ioremap() on ordinary RAM is typically flagged
      as an error if the memory region being mapped is also covered by the
      linear mapping, since that would lead to aliases with conflicting
      cacheability attributes.
      
      Since what we are dealing with is not an I/O region with side effects,
      using ioremap() here is arguably incorrect anyway, so let's replace
      it with memremap() instead.
      Acked-by: NPeter Jones <pjones@redhat.com>
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Leif Lindholm <leif.lindholm@linaro.org>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      f58a37b2
    • M
      efi/esrt: Use efi_mem_reserve() and avoid a kmalloc() · 8e80632f
      Matt Fleming 提交于
      We can use the new efi_mem_reserve() API to mark the ESRT table as
      reserved forever and save ourselves the trouble of copying the data
      out into a kmalloc buffer.
      
      The added advantage is that now the ESRT driver will work across
      kexec reboot.
      
      Tested-by: Dave Young <dyoung@redhat.com> [kexec/kdump]
      Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> [arm]
      Acked-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Leif Lindholm <leif.lindholm@linaro.org>
      Cc: Peter Jones <pjones@redhat.com>
      Cc: Borislav Petkov <bp@alien8.de>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      8e80632f
    • M
      efi/runtime-map: Use efi.memmap directly instead of a copy · 31ce8cc6
      Matt Fleming 提交于
      Now that efi.memmap is available all of the time there's no need to
      allocate and build a separate copy of the EFI memory map.
      
      Furthermore, efi.memmap contains boot services regions but only those
      regions that have been reserved via efi_mem_reserve(). Using
      efi.memmap allows us to pass boot services across kexec reboot so that
      the ESRT and BGRT drivers will now work.
      
      Tested-by: Dave Young <dyoung@redhat.com> [kexec/kdump]
      Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> [arm]
      Acked-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Leif Lindholm <leif.lindholm@linaro.org>
      Cc: Peter Jones <pjones@redhat.com>
      Cc: Borislav Petkov <bp@alien8.de>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      31ce8cc6
    • M
      efi: Allow drivers to reserve boot services forever · 816e7612
      Matt Fleming 提交于
      Today, it is not possible for drivers to reserve EFI boot services for
      access after efi_free_boot_services() has been called on x86. For
      ARM/arm64 it can be done simply by calling memblock_reserve().
      
      Having this ability for all three architectures is desirable for a
      couple of reasons,
      
        1) It saves drivers copying data out of those regions
        2) kexec reboot can now make use of things like ESRT
      
      Instead of using the standard memblock_reserve() which is insufficient
      to reserve the region on x86 (see efi_reserve_boot_services()), a new
      API is introduced in this patch; efi_mem_reserve().
      
      efi.memmap now always represents which EFI memory regions are
      available. On x86 the EFI boot services regions that have not been
      reserved via efi_mem_reserve() will be removed from efi.memmap during
      efi_free_boot_services().
      
      This has implications for kexec, since it is not possible for a newly
      kexec'd kernel to access the same boot services regions that the
      initial boot kernel had access to unless they are reserved by every
      kexec kernel in the chain.
      
      Tested-by: Dave Young <dyoung@redhat.com> [kexec/kdump]
      Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> [arm]
      Acked-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Leif Lindholm <leif.lindholm@linaro.org>
      Cc: Peter Jones <pjones@redhat.com>
      Cc: Borislav Petkov <bp@alien8.de>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      816e7612
    • M
      efi: Add efi_memmap_install() for installing new EFI memory maps · c45f4da3
      Matt Fleming 提交于
      While efi_memmap_init_{early,late}() exist for architecture code to
      install memory maps from firmware data and for the virtual memory
      regions respectively, drivers don't care which stage of the boot we're
      at and just want to swap the existing memmap for a modified one.
      
      efi_memmap_install() abstracts the details of how the new memory map
      should be mapped and the existing one unmapped.
      
      Tested-by: Dave Young <dyoung@redhat.com> [kexec/kdump]
      Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> [arm]
      Acked-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Leif Lindholm <leif.lindholm@linaro.org>
      Cc: Peter Jones <pjones@redhat.com>
      Cc: Borislav Petkov <bp@alien8.de>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: Taku Izumi <izumi.taku@jp.fujitsu.com>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      c45f4da3
    • M
      efi: Split out EFI memory map functions into new file · 60863c0d
      Matt Fleming 提交于
      Also move the functions from the EFI fake mem driver since future
      patches will require access to the memmap insertion code even if
      CONFIG_EFI_FAKE_MEM isn't enabled.
      
      This will be useful when we need to build custom EFI memory maps to
      allow drivers to mark regions as reserved.
      
      Tested-by: Dave Young <dyoung@redhat.com> [kexec/kdump]
      Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> [arm]
      Acked-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Leif Lindholm <leif.lindholm@linaro.org>
      Cc: Peter Jones <pjones@redhat.com>
      Cc: Borislav Petkov <bp@alien8.de>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: Taku Izumi <izumi.taku@jp.fujitsu.com>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      60863c0d
    • M
      efi/fake_mem: Refactor main two code chunks into functions · c8c1a4c5
      Matt Fleming 提交于
      There is a whole load of generic EFI memory map code inside of the
      fake_mem driver which is better suited to being grouped with the rest
      of the generic EFI code for manipulating EFI memory maps.
      
      In preparation for that, this patch refactors the core code, so that
      it's possible to move entire functions later.
      
      Tested-by: Dave Young <dyoung@redhat.com> [kexec/kdump]
      Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> [arm]
      Acked-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Leif Lindholm <leif.lindholm@linaro.org>
      Cc: Peter Jones <pjones@redhat.com>
      Cc: Borislav Petkov <bp@alien8.de>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: Taku Izumi <izumi.taku@jp.fujitsu.com>
      Signed-off-by: NMatt Fleming <matt@codeblueprint.co.uk>
      c8c1a4c5