mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-22 21:21:02 +07:00
34dc0ea6bc
For dma-direct we know that the DMA address is an encoding of the physical address that we can trivially decode. Use that fact to provide implementations that do not need the arch_dma_coherent_to_pfn architecture hook. Note that we still can only support mmap of non-coherent memory only if the architecture provides a way to set an uncached bit in the page tables. This must be true for architectures that use the generic remap helpers, but other architectures can also manually select it. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Max Filippov <jcmvbkbc@gmail.com>
80 lines
2.6 KiB
C
80 lines
2.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _LINUX_DMA_DIRECT_H
|
|
#define _LINUX_DMA_DIRECT_H 1
|
|
|
|
#include <linux/dma-mapping.h>
|
|
#include <linux/mem_encrypt.h>
|
|
|
|
#ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA
|
|
#include <asm/dma-direct.h>
|
|
#else
|
|
static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
|
|
{
|
|
dma_addr_t dev_addr = (dma_addr_t)paddr;
|
|
|
|
return dev_addr - ((dma_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
|
|
}
|
|
|
|
static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dev_addr)
|
|
{
|
|
phys_addr_t paddr = (phys_addr_t)dev_addr;
|
|
|
|
return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
|
|
}
|
|
|
|
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
|
|
{
|
|
if (!dev->dma_mask)
|
|
return false;
|
|
|
|
return addr + size - 1 <=
|
|
min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
|
|
}
|
|
#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
|
|
|
|
#ifdef CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED
|
|
bool force_dma_unencrypted(struct device *dev);
|
|
#else
|
|
static inline bool force_dma_unencrypted(struct device *dev)
|
|
{
|
|
return false;
|
|
}
|
|
#endif /* CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED */
|
|
|
|
/*
|
|
* If memory encryption is supported, phys_to_dma will set the memory encryption
|
|
* bit in the DMA address, and dma_to_phys will clear it. The raw __phys_to_dma
|
|
* and __dma_to_phys versions should only be used on non-encrypted memory for
|
|
* special occasions like DMA coherent buffers.
|
|
*/
|
|
static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
|
|
{
|
|
return __sme_set(__phys_to_dma(dev, paddr));
|
|
}
|
|
|
|
static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
|
|
{
|
|
return __sme_clr(__dma_to_phys(dev, daddr));
|
|
}
|
|
|
|
u64 dma_direct_get_required_mask(struct device *dev);
|
|
void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
|
|
gfp_t gfp, unsigned long attrs);
|
|
void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
|
|
dma_addr_t dma_addr, unsigned long attrs);
|
|
void *dma_direct_alloc_pages(struct device *dev, size_t size,
|
|
dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs);
|
|
void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr,
|
|
dma_addr_t dma_addr, unsigned long attrs);
|
|
struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
|
|
gfp_t gfp, unsigned long attrs);
|
|
int dma_direct_get_sgtable(struct device *dev, struct sg_table *sgt,
|
|
void *cpu_addr, dma_addr_t dma_addr, size_t size,
|
|
unsigned long attrs);
|
|
bool dma_direct_can_mmap(struct device *dev);
|
|
int dma_direct_mmap(struct device *dev, struct vm_area_struct *vma,
|
|
void *cpu_addr, dma_addr_t dma_addr, size_t size,
|
|
unsigned long attrs);
|
|
int dma_direct_supported(struct device *dev, u64 mask);
|
|
#endif /* _LINUX_DMA_DIRECT_H */
|