Merge tag 'dma-mapping-5.3-1' of git://git.infradead.org/users/hch/dma-mapping
Pull dma-mapping fixes from Christoph Hellwig: "Fix various regressions: - force unencrypted dma-coherent buffers if encryption bit can't fit into the dma coherent mask (Tom Lendacky) - avoid limiting request size if swiotlb is not used (me) - fix swiotlb handling in dma_direct_sync_sg_for_cpu/device (Fugang Duan)" * tag 'dma-mapping-5.3-1' of git://git.infradead.org/users/hch/dma-mapping: dma-direct: correct the physical addr in dma_direct_sync_sg_for_cpu/device dma-direct: only limit the mapping size if swiotlb could be used dma-mapping: add a dma_addressing_limited helper dma-direct: Force unencrypted DMA under SME for certain DMA masks
This commit is contained in:
@@ -48,6 +48,9 @@ config ARCH_HAS_DMA_COHERENT_TO_PFN
|
||||
config ARCH_HAS_DMA_MMAP_PGPROT
|
||||
bool
|
||||
|
||||
config ARCH_HAS_FORCE_DMA_UNENCRYPTED
|
||||
bool
|
||||
|
||||
config DMA_NONCOHERENT_CACHE_SYNC
|
||||
bool
|
||||
|
||||
|
@@ -23,14 +23,6 @@
|
||||
#define ARCH_ZONE_DMA_BITS 24
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For AMD SEV all DMA must be to unencrypted addresses.
|
||||
*/
|
||||
static inline bool force_dma_unencrypted(void)
|
||||
{
|
||||
return sev_active();
|
||||
}
|
||||
|
||||
static void report_addr(struct device *dev, dma_addr_t dma_addr, size_t size)
|
||||
{
|
||||
if (!dev->dma_mask) {
|
||||
@@ -46,7 +38,7 @@ static void report_addr(struct device *dev, dma_addr_t dma_addr, size_t size)
|
||||
static inline dma_addr_t phys_to_dma_direct(struct device *dev,
|
||||
phys_addr_t phys)
|
||||
{
|
||||
if (force_dma_unencrypted())
|
||||
if (force_dma_unencrypted(dev))
|
||||
return __phys_to_dma(dev, phys);
|
||||
return phys_to_dma(dev, phys);
|
||||
}
|
||||
@@ -67,7 +59,7 @@ static gfp_t __dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask,
|
||||
if (dev->bus_dma_mask && dev->bus_dma_mask < dma_mask)
|
||||
dma_mask = dev->bus_dma_mask;
|
||||
|
||||
if (force_dma_unencrypted())
|
||||
if (force_dma_unencrypted(dev))
|
||||
*phys_mask = __dma_to_phys(dev, dma_mask);
|
||||
else
|
||||
*phys_mask = dma_to_phys(dev, dma_mask);
|
||||
@@ -159,7 +151,7 @@ void *dma_direct_alloc_pages(struct device *dev, size_t size,
|
||||
}
|
||||
|
||||
ret = page_address(page);
|
||||
if (force_dma_unencrypted()) {
|
||||
if (force_dma_unencrypted(dev)) {
|
||||
set_memory_decrypted((unsigned long)ret, 1 << get_order(size));
|
||||
*dma_handle = __phys_to_dma(dev, page_to_phys(page));
|
||||
} else {
|
||||
@@ -192,7 +184,7 @@ void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr,
|
||||
return;
|
||||
}
|
||||
|
||||
if (force_dma_unencrypted())
|
||||
if (force_dma_unencrypted(dev))
|
||||
set_memory_encrypted((unsigned long)cpu_addr, 1 << page_order);
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARCH_HAS_UNCACHED_SEGMENT) &&
|
||||
@@ -242,12 +234,14 @@ void dma_direct_sync_sg_for_device(struct device *dev,
|
||||
int i;
|
||||
|
||||
for_each_sg(sgl, sg, nents, i) {
|
||||
if (unlikely(is_swiotlb_buffer(sg_phys(sg))))
|
||||
swiotlb_tbl_sync_single(dev, sg_phys(sg), sg->length,
|
||||
phys_addr_t paddr = dma_to_phys(dev, sg_dma_address(sg));
|
||||
|
||||
if (unlikely(is_swiotlb_buffer(paddr)))
|
||||
swiotlb_tbl_sync_single(dev, paddr, sg->length,
|
||||
dir, SYNC_FOR_DEVICE);
|
||||
|
||||
if (!dev_is_dma_coherent(dev))
|
||||
arch_sync_dma_for_device(dev, sg_phys(sg), sg->length,
|
||||
arch_sync_dma_for_device(dev, paddr, sg->length,
|
||||
dir);
|
||||
}
|
||||
}
|
||||
@@ -279,11 +273,13 @@ void dma_direct_sync_sg_for_cpu(struct device *dev,
|
||||
int i;
|
||||
|
||||
for_each_sg(sgl, sg, nents, i) {
|
||||
phys_addr_t paddr = dma_to_phys(dev, sg_dma_address(sg));
|
||||
|
||||
if (!dev_is_dma_coherent(dev))
|
||||
arch_sync_dma_for_cpu(dev, sg_phys(sg), sg->length, dir);
|
||||
|
||||
if (unlikely(is_swiotlb_buffer(sg_phys(sg))))
|
||||
swiotlb_tbl_sync_single(dev, sg_phys(sg), sg->length, dir,
|
||||
arch_sync_dma_for_cpu(dev, paddr, sg->length, dir);
|
||||
|
||||
if (unlikely(is_swiotlb_buffer(paddr)))
|
||||
swiotlb_tbl_sync_single(dev, paddr, sg->length, dir,
|
||||
SYNC_FOR_CPU);
|
||||
}
|
||||
|
||||
@@ -407,11 +403,9 @@ int dma_direct_supported(struct device *dev, u64 mask)
|
||||
|
||||
size_t dma_direct_max_mapping_size(struct device *dev)
|
||||
{
|
||||
size_t size = SIZE_MAX;
|
||||
|
||||
/* If SWIOTLB is active, use its maximum mapping size */
|
||||
if (is_swiotlb_active())
|
||||
size = swiotlb_max_mapping_size(dev);
|
||||
|
||||
return size;
|
||||
if (is_swiotlb_active() &&
|
||||
(dma_addressing_limited(dev) || swiotlb_force == SWIOTLB_FORCE))
|
||||
return swiotlb_max_mapping_size(dev);
|
||||
return SIZE_MAX;
|
||||
}
|
||||
|
Reference in New Issue
Block a user