aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/efi.h
diff options
context:
space:
mode:
authorMatthew Garrett <matthewgarrett@google.com>2020-01-03 12:39:50 +0100
committerIngo Molnar <mingo@kernel.org>2020-01-10 18:55:04 +0100
commit4444f8541dad16fefd9b8807ad1451e806ef1d94 (patch)
tree6a8d8197da3e6f1cc355732af0f3a8a143fd5509 /include/linux/efi.h
parentefi/x86: Allow translating 64-bit arguments for mixed mode calls (diff)
downloadlinux-dev-4444f8541dad16fefd9b8807ad1451e806ef1d94.tar.xz
linux-dev-4444f8541dad16fefd9b8807ad1451e806ef1d94.zip
efi: Allow disabling PCI busmastering on bridges during boot
Add an option to disable the busmaster bit in the control register on all PCI bridges before calling ExitBootServices() and passing control to the runtime kernel. System firmware may configure the IOMMU to prevent malicious PCI devices from being able to attack the OS via DMA. However, since firmware can't guarantee that the OS is IOMMU-aware, it will tear down IOMMU configuration when ExitBootServices() is called. This leaves a window between where a hostile device could still cause damage before Linux configures the IOMMU again. If CONFIG_EFI_DISABLE_PCI_DMA is enabled or "efi=disable_early_pci_dma" is passed on the command line, the EFI stub will clear the busmaster bit on all PCI bridges before ExitBootServices() is called. This will prevent any malicious PCI devices from being able to perform DMA until the kernel reenables busmastering after configuring the IOMMU. This option may cause failures with some poorly behaved hardware and should not be enabled without testing. The kernel commandline options "efi=disable_early_pci_dma" or "efi=no_disable_early_pci_dma" may be used to override the default. Note that PCI devices downstream from PCI bridges are disconnected from their drivers first, using the UEFI driver model API, so that DMA can be disabled safely at the bridge level. [ardb: disconnect PCI I/O handles first, as suggested by Arvind] Co-developed-by: Matthew Garrett <mjg59@google.com> Signed-off-by: Matthew Garrett <mjg59@google.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Arvind Sankar <nivedita@alum.mit.edu> Cc: Matthew Garrett <matthewgarrett@google.com> Cc: linux-efi@vger.kernel.org Link: https://lkml.kernel.org/r/20200103113953.9571-18-ardb@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'include/linux/efi.h')
-rw-r--r--include/linux/efi.h6
1 files changed, 5 insertions, 1 deletions
diff --git a/include/linux/efi.h b/include/linux/efi.h
index ee68ea6f85ff..7e8e25b1d11c 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -319,7 +319,9 @@ typedef union {
void *stall;
void *set_watchdog_timer;
void *connect_controller;
- void *disconnect_controller;
+ efi_status_t (__efiapi *disconnect_controller)(efi_handle_t,
+ efi_handle_t,
+ efi_handle_t);
void *open_protocol;
void *close_protocol;
void *open_protocol_information;
@@ -1692,4 +1694,6 @@ struct linux_efi_memreserve {
#define EFI_MEMRESERVE_COUNT(size) (((size) - sizeof(struct linux_efi_memreserve)) \
/ sizeof(((struct linux_efi_memreserve *)0)->entry[0]))
+void efi_pci_disable_bridge_busmaster(void);
+
#endif /* _LINUX_EFI_H */