summaryrefslogtreecommitdiff
path: root/drivers/firmware
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2023-06-27 09:33:09 +0200
committerArd Biesheuvel <ardb@kernel.org>2023-06-27 12:27:06 +0200
commit2e28a798c3092ea42b968fa16ac835969d124898 (patch)
treea949db7699fcf213f91d7711db3a4bc7bc46f912 /drivers/firmware
parentd0a1865cf7e2211d9227592ef4141f4632e33908 (diff)
efi/libstub: Disable PCI DMA before grabbing the EFI memory map
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: 4444f8541dad16fe ("efi: Allow disabling PCI busmastering on bridges during boot") Reported-by: Glenn Washburn <development@efficientek.com> Acked-by: Matthew Garrett <mjg59@srcf.ucam.org> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/efi/libstub/efi-stub-helper.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index 1e0203d74691..732984295295 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -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) {