Skip to content

Commit f07d141

Browse files
rmurphy-armChristoph Hellwig
authored andcommitted
dma-mapping: Generalise dma_32bit_limit flag
Whilst the notion of an upstream DMA restriction is most commonly seen in PCI host bridges saddled with a 32-bit native interface, a more general version of the same issue can exist on complex SoCs where a bus or point-to-point interconnect link from a device's DMA master interface to another component along the path to memory (often an IOMMU) may carry fewer address bits than the interfaces at both ends nominally support. In order to properly deal with this, the first step is to expand the dma_32bit_limit flag into an arbitrary mask. To minimise the impact on existing code, we'll make sure to only consider this new mask valid if set. That makes sense anyway, since a mask of zero would represent DMA not being wired up at all, and that would be better handled by not providing valid ops in the first place. Signed-off-by: Robin Murphy <robin.murphy@arm.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Christoph Hellwig <hch@lst.de>
1 parent 5ac65e8 commit f07d141

File tree

3 files changed

+7
-7
lines changed

3 files changed

+7
-7
lines changed

arch/x86/kernel/pci-dma.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ rootfs_initcall(pci_iommu_init);
175175

176176
static int via_no_dac_cb(struct pci_dev *pdev, void *data)
177177
{
178-
pdev->dev.dma_32bit_limit = true;
178+
pdev->dev.bus_dma_mask = DMA_BIT_MASK(32);
179179
return 0;
180180
}
181181

include/linux/device.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,8 @@ struct dev_links_info {
886886
* @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all
887887
* hardware supports 64-bit addresses for consistent allocations
888888
* such descriptors.
889+
* @bus_dma_mask: Mask of an upstream bridge or bus which imposes a smaller DMA
890+
* limit than the device itself supports.
889891
* @dma_pfn_offset: offset of DMA memory range relatively of RAM
890892
* @dma_parms: A low level driver may set these to teach IOMMU code about
891893
* segment limitations.
@@ -912,8 +914,6 @@ struct dev_links_info {
912914
* @offline: Set after successful invocation of bus type's .offline().
913915
* @of_node_reused: Set if the device-tree node is shared with an ancestor
914916
* device.
915-
* @dma_32bit_limit: bridge limited to 32bit DMA even if the device itself
916-
* indicates support for a higher limit in the dma_mask field.
917917
*
918918
* At the lowest level, every device in a Linux system is represented by an
919919
* instance of struct device. The device structure contains the information
@@ -967,6 +967,7 @@ struct device {
967967
not all hardware supports
968968
64 bit addresses for consistent
969969
allocations such descriptors. */
970+
u64 bus_dma_mask; /* upstream dma_mask constraint */
970971
unsigned long dma_pfn_offset;
971972

972973
struct device_dma_parameters *dma_parms;
@@ -1002,7 +1003,6 @@ struct device {
10021003
bool offline_disabled:1;
10031004
bool offline:1;
10041005
bool of_node_reused:1;
1005-
bool dma_32bit_limit:1;
10061006
};
10071007

10081008
static inline struct device *kobj_to_dev(struct kobject *kobj)

kernel/dma/direct.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,10 @@ int dma_direct_supported(struct device *dev, u64 mask)
180180
return 0;
181181
#endif
182182
/*
183-
* Various PCI/PCIe bridges have broken support for > 32bit DMA even
184-
* if the device itself might support it.
183+
* Upstream PCI/PCIe bridges or SoC interconnects may not carry
184+
* as many DMA address bits as the device itself supports.
185185
*/
186-
if (dev->dma_32bit_limit && mask > DMA_BIT_MASK(32))
186+
if (dev->bus_dma_mask && mask > dev->bus_dma_mask)
187187
return 0;
188188
return 1;
189189
}

0 commit comments

Comments
 (0)