Message ID | 1473067049-16252-7-git-send-email-ard.biesheuvel@linaro.org |
---|---|
State | Accepted |
Commit | e58a71d9c50ba641b5ab19f5ce2cbf772187de4d |
Headers | show |
On 09/05/16 11:17, Ard Biesheuvel wrote: > Currently, the EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE attribute is completely > ignored by the PCI host bridge driver, which means that, on an implementation > that supports DMA above 4 GB, allocations above 4 GB may be provided to > devices that have not expressed support for it. > > So in addition to checking 'RootBridge->DmaAbove4G' to establish whether the > root bridge itself supports DMA above 4 GB, we must also take into account > the operation type (EfiPciOperationBusMaster{Read|Write|CommBuffer}64), > and the EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE attribute, when mapping and > allocating DMA memory, respectively. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> > --- > MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 14 ++++++++++---- > 1 file changed, 10 insertions(+), 4 deletions(-) > > diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c > index b2d76d67afa2..8af131b0af37 100644 > --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c > +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c > @@ -1073,10 +1073,15 @@ RootBridgeIoMap ( > RootBridge = ROOT_BRIDGE_FROM_THIS (This); > > PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress; > - if (!RootBridge->DmaAbove4G && ((PhysicalAddress + *NumberOfBytes) > SIZE_4GB)) { > + if ((!RootBridge->DmaAbove4G || > + (Operation != EfiPciOperationBusMasterRead64 && > + Operation != EfiPciOperationBusMasterWrite64 && > + Operation != EfiPciOperationBusMasterCommonBuffer64)) && > + ((PhysicalAddress + *NumberOfBytes) > SIZE_4GB)) { > + > // > - // If the root bridge can not handle performing DMA above 4GB but > - // any part of the DMA transfer being mapped is above 4GB, then > + // If the root bridge or the device cannot handle performing DMA above > + // 4GB but any part of the DMA transfer being mapped is above 4GB, then > // map the DMA transfer to a buffer below 4GB. > // > > @@ -1308,7 +1313,8 @@ RootBridgeIoAllocateBuffer ( > RootBridge = ROOT_BRIDGE_FROM_THIS (This); > > AllocateType = AllocateAnyPages; > - if (!RootBridge->DmaAbove4G) { > + if (!RootBridge->DmaAbove4G || > + (Attributes & EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) { > // > // Limit allocations to memory below 4GB > // > Reviewed-by: Laszlo Ersek <lersek@redhat.com> _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c index b2d76d67afa2..8af131b0af37 100644 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c @@ -1073,10 +1073,15 @@ RootBridgeIoMap ( RootBridge = ROOT_BRIDGE_FROM_THIS (This); PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress; - if (!RootBridge->DmaAbove4G && ((PhysicalAddress + *NumberOfBytes) > SIZE_4GB)) { + if ((!RootBridge->DmaAbove4G || + (Operation != EfiPciOperationBusMasterRead64 && + Operation != EfiPciOperationBusMasterWrite64 && + Operation != EfiPciOperationBusMasterCommonBuffer64)) && + ((PhysicalAddress + *NumberOfBytes) > SIZE_4GB)) { + // - // If the root bridge can not handle performing DMA above 4GB but - // any part of the DMA transfer being mapped is above 4GB, then + // If the root bridge or the device cannot handle performing DMA above + // 4GB but any part of the DMA transfer being mapped is above 4GB, then // map the DMA transfer to a buffer below 4GB. // @@ -1308,7 +1313,8 @@ RootBridgeIoAllocateBuffer ( RootBridge = ROOT_BRIDGE_FROM_THIS (This); AllocateType = AllocateAnyPages; - if (!RootBridge->DmaAbove4G) { + if (!RootBridge->DmaAbove4G || + (Attributes & EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) { // // Limit allocations to memory below 4GB //
Currently, the EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE attribute is completely ignored by the PCI host bridge driver, which means that, on an implementation that supports DMA above 4 GB, allocations above 4 GB may be provided to devices that have not expressed support for it. So in addition to checking 'RootBridge->DmaAbove4G' to establish whether the root bridge itself supports DMA above 4 GB, we must also take into account the operation type (EfiPciOperationBusMaster{Read|Write|CommBuffer}64), and the EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE attribute, when mapping and allocating DMA memory, respectively. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> --- MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel