dma-direct: Force unencrypted DMA under SME for certain DMA masks
authorTom Lendacky <thomas.lendacky@amd.com>
Wed, 10 Jul 2019 19:01:19 +0000 (19:01 +0000)
committerChristoph Hellwig <hch@lst.de>
Tue, 16 Jul 2019 20:15:46 +0000 (22:15 +0200)
commit9087c37584fb7d8315877bb55f85e4268cc0b4f4
tree11f256332491057cf19db8aa447d44465bec79da
parent9637d517347e80ee2fe1c5d8ce45ba1b88d8b5cd
dma-direct: Force unencrypted DMA under SME for certain DMA masks

If a device doesn't support DMA to a physical address that includes the
encryption bit (currently bit 47, so 48-bit DMA), then the DMA must
occur to unencrypted memory. SWIOTLB is used to satisfy that requirement
if an IOMMU is not active (enabled or configured in passthrough mode).

However, commit fafadcd16595 ("swiotlb: don't dip into swiotlb pool for
coherent allocations") modified the coherent allocation support in
SWIOTLB to use the DMA direct coherent allocation support. When an IOMMU
is not active, this resulted in dma_alloc_coherent() failing for devices
that didn't support DMA addresses that included the encryption bit.

Addressing this requires changes to the force_dma_unencrypted() function
in kernel/dma/direct.c. Since the function is now non-trivial and
SME/SEV specific, update the DMA direct support to add an arch override
for the force_dma_unencrypted() function. The arch override is selected
when CONFIG_AMD_MEM_ENCRYPT is set. The arch override function resides in
the arch/x86/mm/mem_encrypt.c file and forces unencrypted DMA when either
SEV is active or SME is active and the device does not support DMA to
physical addresses that include the encryption bit.

Fixes: fafadcd16595 ("swiotlb: don't dip into swiotlb pool for coherent allocations")
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
[hch: moved the force_dma_unencrypted declaration to dma-mapping.h,
      fold the s390 fix from Halil Pasic]
Signed-off-by: Christoph Hellwig <hch@lst.de>
arch/s390/Kconfig
arch/s390/mm/init.c
arch/x86/Kconfig
arch/x86/mm/mem_encrypt.c
include/linux/dma-direct.h
kernel/dma/Kconfig
kernel/dma/direct.c