Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dma: Introduce generic dma_addr_*crypted helpers

AMD SME added __sme_set/__sme_clr primitives to modify the DMA address for
encrypted/decrypted traffic. However this doesn't fit in with other models,
e.g., Arm CCA where the meanings are the opposite. i.e., "decrypted" traffic
has a bit set and "encrypted" traffic has the top bit cleared.

In preparation for adding the support for Arm CCA DMA conversions, convert the
existing primitives to more generic ones that can be provided by the backends.
i.e., add helpers to
1. dma_addr_encrypted - Convert a DMA address to "encrypted" [ == __sme_set() ]
2. dma_addr_unencrypted - Convert a DMA address to "decrypted" [ None exists today ]
3. dma_addr_canonical - Clear any "encryption"/"decryption" bits from DMA
address [ SME uses __sme_clr() ] and convert to a canonical DMA address.

Since the original __sme_xxx helpers come from linux/mem_encrypt.h, use that
as the home for the new definitions and provide dummy ones when none is provided
by the architectures.

With the above, phys_to_dma_unencrypted() uses the newly added dma_addr_unencrypted()
helper and to make it a bit more easier to read and avoid double conversion,
provide __phys_to_dma().

Suggested-by: Robin Murphy <robin.murphy@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Jean-Philippe Brucker <jean-philippe@linaro.org>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Steven Price <steven.price@arm.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Gavin Shan <gshan@redhat.com>
Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
Fixes: 42be24a4178f ("arm64: Enable memory encrypt for Realms")
Acked-by: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20250227144150.1667735-3-suzuki.poulose@arm.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

authored by

Suzuki K Poulose and committed by
Catalin Marinas
b66e2ee7 c3809317

+31 -4
+8 -4
include/linux/dma-direct.h
··· 78 78 #define phys_to_dma_unencrypted phys_to_dma 79 79 #endif 80 80 #else 81 - static inline dma_addr_t phys_to_dma_unencrypted(struct device *dev, 82 - phys_addr_t paddr) 81 + static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) 83 82 { 84 83 if (dev->dma_range_map) 85 84 return translate_phys_to_dma(dev, paddr); 86 85 return paddr; 87 86 } 88 87 88 + static inline dma_addr_t phys_to_dma_unencrypted(struct device *dev, 89 + phys_addr_t paddr) 90 + { 91 + return dma_addr_unencrypted(__phys_to_dma(dev, paddr)); 92 + } 89 93 /* 90 94 * If memory encryption is supported, phys_to_dma will set the memory encryption 91 95 * bit in the DMA address, and dma_to_phys will clear it. ··· 98 94 */ 99 95 static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) 100 96 { 101 - return __sme_set(phys_to_dma_unencrypted(dev, paddr)); 97 + return dma_addr_encrypted(__phys_to_dma(dev, paddr)); 102 98 } 103 99 104 100 static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr) 105 101 { 106 102 phys_addr_t paddr; 107 103 108 - dma_addr = __sme_clr(dma_addr); 104 + dma_addr = dma_addr_canonical(dma_addr); 109 105 if (dev->dma_range_map) 110 106 paddr = translate_dma_to_phys(dev, dma_addr); 111 107 else
+23
include/linux/mem_encrypt.h
··· 26 26 */ 27 27 #define __sme_set(x) ((x) | sme_me_mask) 28 28 #define __sme_clr(x) ((x) & ~sme_me_mask) 29 + 30 + #define dma_addr_encrypted(x) __sme_set(x) 31 + #define dma_addr_canonical(x) __sme_clr(x) 32 + 29 33 #else 30 34 #define __sme_set(x) (x) 31 35 #define __sme_clr(x) (x) 36 + #endif 37 + 38 + /* 39 + * dma_addr_encrypted() and dma_addr_unencrypted() are for converting a given DMA 40 + * address to the respective type of addressing. 41 + * 42 + * dma_addr_canonical() is used to reverse any conversions for encrypted/decrypted 43 + * back to the canonical address. 44 + */ 45 + #ifndef dma_addr_encrypted 46 + #define dma_addr_encrypted(x) (x) 47 + #endif 48 + 49 + #ifndef dma_addr_unencrypted 50 + #define dma_addr_unencrypted(x) (x) 51 + #endif 52 + 53 + #ifndef dma_addr_canonical 54 + #define dma_addr_canonical(x) (x) 32 55 #endif 33 56 34 57 #endif /* __ASSEMBLY__ */