Add a function to force direct ops and disable swiotlb for a deivce. Signed-off-by: Jonathan Marek <jonat...@marek.ca> --- include/linux/dma-direct.h | 9 +++++++++ kernel/dma/direct.c | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+)
diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h index 18aade195884..41f57e1b7aa5 100644 --- a/include/linux/dma-direct.h +++ b/include/linux/dma-direct.h @@ -124,4 +124,13 @@ int dma_direct_supported(struct device *dev, u64 mask); dma_addr_t dma_direct_map_resource(struct device *dev, phys_addr_t paddr, size_t size, enum dma_data_direction dir, unsigned long attrs); +#if IS_ENABLED(CONFIG_DMA_OPS_BYPASS) && !IS_ENABLED(CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED) +int dma_direct_bypass(struct device *dev); +#else +static inline int dma_direct_bypass(struct device *dev) +{ + return -EIO; +} +#endif + #endif /* _LINUX_DMA_DIRECT_H */ diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index 06c111544f61..304a5a77cccb 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -548,3 +548,26 @@ int dma_direct_set_offset(struct device *dev, phys_addr_t cpu_start, return 0; } EXPORT_SYMBOL_GPL(dma_direct_set_offset); + +/** + * dma_direct_bypass - always use direct mapping path for device + * @dev: device pointer + * + * Note: this also bypasses swiotlb. Not available for arch with + * force_dma_unencrypted(), since this doesn't deal with that. + */ +#if IS_ENABLED(CONFIG_DMA_OPS_BYPASS) && !IS_ENABLED(CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED) +int dma_direct_bypass(struct device *dev) +{ + int ret; + + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); + if (ret) + return ret; + + dev->bus_dma_limit = DMA_BIT_MASK(64); + dev->dma_ops_bypass = true; + return 0; +} +EXPORT_SYMBOL_GPL(dma_direct_bypass); +#endif -- 2.26.1