Skip to content
Snippets Groups Projects
Commit 1df929db authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Greg Kroah-Hartman
Browse files

efi/libstub: Disable PCI DMA before grabbing the EFI memory map


[ Upstream commit 2e28a798 ]

Currently, the EFI stub will disable PCI DMA as the very last thing it
does before calling ExitBootServices(), to avoid interfering with the
firmware's normal operation as much as possible.

However, the stub will invoke DisconnectController() on all endpoints
downstream of the PCI bridges it disables, and this may affect the
layout of the EFI memory map, making it substantially more likely that
ExitBootServices() will fail the first time around, and that the EFI
memory map needs to be reloaded.

This, in turn, increases the likelihood that the slack space we
allocated is insufficient (and we can no longer allocate memory via boot
services after having called ExitBootServices() once), causing the
second call to GetMemoryMap (and therefore the boot) to fail. This makes
the PCI DMA disable feature a bit more fragile than it already is, so
let's make it more robust, by allocating the space for the EFI memory
map after disabling PCI DMA.

Fixes: 4444f854 ("efi: Allow disabling PCI busmastering on bridges during boot")
Reported-by: default avatarGlenn Washburn <development@efficientek.com>
Acked-by: default avatarMatthew Garrett <mjg59@srcf.ucam.org>
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent a1263fd2
No related branches found
No related tags found
No related merge requests found
......@@ -378,6 +378,9 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv,
struct efi_boot_memmap *map;
efi_status_t status;
if (efi_disable_pci_dma)
efi_pci_disable_bridge_busmaster();
status = efi_get_memory_map(&map, true);
if (status != EFI_SUCCESS)
return status;
......@@ -388,9 +391,6 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv,
return status;
}
if (efi_disable_pci_dma)
efi_pci_disable_bridge_busmaster();
status = efi_bs_call(exit_boot_services, handle, map->map_key);
if (status == EFI_INVALID_PARAMETER) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment