All of lore.kernel.org
 help / color / mirror / Atom feed
From: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
To: Robin Murphy <robin.murphy@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	linux-kernel@vger.kernel.org, iommu@lists.linux.dev,
	linux-coco@lists.linux.dev
Cc: Catalin Marinas <catalin.marinas@arm.com>,
	will@kernel.org, jgg@ziepe.ca, steven.price@arm.com,
	Marek Szyprowski <m.szyprowski@samsung.com>
Subject: Re: [PATCH 1/2] dma-direct: Validate DMA mask against canonical DMA addresses
Date: Wed, 21 Jan 2026 10:20:48 +0530	[thread overview]
Message-ID: <yq5ajyxbk1qv.fsf@kernel.org> (raw)
In-Reply-To: <b662e137-5d2a-4ee7-b1f7-b4545388d4fe@arm.com>

Robin Murphy <robin.murphy@arm.com> writes:

> On 2026-01-20 2:25 pm, Aneesh Kumar K.V wrote:
>> Robin Murphy <robin.murphy@arm.com> writes:
>> 
>>> On 2026-01-20 9:59 am, Suzuki K Poulose wrote:
>>>> On 20/01/2026 06:42, Aneesh Kumar K.V (Arm) wrote:
>>>>> On systems that apply an address encryption tag or mask to DMA addresses,
>>>>> DMA mask validation must be performed against the canonical DMA address.
>>>>> Using a non-canonical (e.g. encrypted or unencrypted) DMA address
>>>>> can incorrectly fail capability checks, since architecture-specific
>>>>> encryption bits are not part of the device’s actual DMA addressing
>>>>> capability. For example, arm64 adds PROT_NS_SHARED to unencrypted DMA
>>>>> addresses.
>>>>>
>>>>> Fix this by validating device DMA masks against __phys_to_dma(), ensuring
>>>>> that the architecture encryption mask does not influence the check.
>>>>>
>>>>> Fixes: b66e2ee7b6c8 ("dma: Introduce generic dma_addr_*crypted helpers")
>>>>
>>>>
>>>>> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
>>>>> ---
>>>>>    kernel/dma/direct.c | 4 ++--
>>>>>    1 file changed, 2 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
>>>>> index 8e04f72baaa3..a5639e9415f5 100644
>>>>> --- a/kernel/dma/direct.c
>>>>> +++ b/kernel/dma/direct.c
>>>>> @@ -580,12 +580,12 @@ int dma_direct_supported(struct device *dev, u64
>>>>> mask)
>>>>>        /*
>>>>>         * This check needs to be against the actual bit mask value, so use
>>>>> -     * phys_to_dma_unencrypted() here so that the SME encryption mask
>>>>> isn't
>>>>> +     * __phys_to_dma() here so that the arch specific encryption mask
>>>>> isn't
>>>>>         * part of the check.
>>>>>         */
>>>>>        if (IS_ENABLED(CONFIG_ZONE_DMA))
>>>>>            min_mask = min_t(u64, min_mask, zone_dma_limit);
>>>>> -    return mask >= phys_to_dma_unencrypted(dev, min_mask);
>>>>> +    return mask >= __phys_to_dma(dev, min_mask);
>>>>
>>>> This is wrong, isn't it ? For e.g., for CCA, even though the "Flag" is
>>>> added to the PA, it is really part of the actual "PA" and thus must be
>>>> checked against the full PA ?
>>>
>>> Yes, it's much the same as for AMD SEV (albeit the other way round) -
>>> the encryption/decryption bit is part of the DMA address because it
>>> needs to be driven by the device, so it is crucial that the device's DMA
>>> mask is capable of expressing that.
>>>
>> 
>> Commit c92a54cfa0257e8ffd66b2a17d49e9c0bd4b769f explains these details.
>
> See x86's force_dma_unencrypted() implementation - the reason dma-direct 
> doesn't need to be so strict for that is because things are the right 
> way round that it can always fall back to shared/untrusted DMA as the 
> general case, and a device can only access an encrypted page directly if 
> it *can* drive the SME bit in the input address to trigger the inline 
> encryption engine.
>
> For CCA we have rather the opposite, where dma-direct requires a device 
> to be able to address any IPA directly to be sure of working at all, but 
> if we do happen to have a stage 1 IOMMU then we could rely on that to 
> map smaller IOVAs to the upper IPA space.
>
>> I was wondering whether the DMA-enable operation should live outside the
>> set_mask operation. Conceptually, set_mask should be derived purely from
>> max_pfn, while the DMA enablement path could additionally verify whether
>> the device requires access to an alias address, depending on whether it
>> is operating in trusted or untrusted mode?
>
> No, the point of the set_mask check is "is this mask big enough to 
> accommodate any *DMA address* we might need to give the device?" - that 
> includes offsets, magic bits, magic bits encoded as fake offsets (yes 
> you, Raspberry Pi...) and whatever else might comprise an actual DMA 
> address as handed off to the hardware. It is *not* directly a "can this 
> device DMA to all RAM we know about?" check - that is in the assumption 
> that if necessary the SWIOTLB buffer will be reachable at a <=32-bit DMA 
> address, and thus we should not *need* to give >32-bit addresses to 
> devices. It is only that assumption which fundamentally falls apart for 
> CCA (with more than 2GB of IPA space, at least).
>

We need the below change then? commit 91ef26f914171cf753330f13724fd9142b5b1640
discuss some hardware that is broken with the usage of phys_to_dma conversion. 

modified   kernel/dma/direct.c
@@ -14,6 +14,7 @@
 #include <linux/set_memory.h>
 #include <linux/slab.h>
 #include <linux/pci-p2pdma.h>
+#include <linux/cc_platform.h>
 #include "direct.h"
 
 /*
@@ -579,17 +580,23 @@ int dma_direct_mmap(struct device *dev, struct vm_area_struct *vma,
 
 int dma_direct_supported(struct device *dev, u64 mask)
 {
-	u64 min_mask = (max_pfn - 1) << PAGE_SHIFT;
+	u64 min_mask = DMA_BIT_MASK(32);
 
 	/*
-	 * Because 32-bit DMA masks are so common we expect every architecture
-	 * to be able to satisfy them - either by not supporting more physical
-	 * memory, or by providing a ZONE_DMA32.  If neither is the case, the
-	 * architecture needs to use an IOMMU instead of the direct mapping.
+	 * Only do the conversion for CC platform, to be compatible
+	 * commit 91ef26f914171cf753330f13724fd9142b5b1640
 	 */
-	if (mask >= DMA_BIT_MASK(32))
+	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
+		min_mask = phys_to_dma_unencrypted(dev, min_mask);
+
+	/*
+	 * if we support ZONE_DMA32 and device mask can cover the DMA32 range,
+	 * then we can support direct dma for any max_pfn value using swiotlb.
+	 */
+	if (IS_ENABLED(CONFIG_ZONE_DMA32) && mask >= min_mask)
 		return 1;
 
+	min_mask = (max_pfn - 1) << PAGE_SHIFT;
 	/*
 	 * This check needs to be against the actual bit mask value, so use
 	 * __phys_to_dma() here so that the arch specific encryption mask isn't


-aneesh

  reply	other threads:[~2026-01-21  4:51 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-20  6:42 [PATCH 1/2] dma-direct: Validate DMA mask against canonical DMA addresses Aneesh Kumar K.V (Arm)
2026-01-20  6:42 ` [PATCH 2/2] dma-direct: Make phys_to_dma() pick encrypted vs unencrypted per device Aneesh Kumar K.V (Arm)
2026-01-20  9:33   ` kernel test robot
2026-01-20 10:49   ` kernel test robot
2026-01-20  9:59 ` [PATCH 1/2] dma-direct: Validate DMA mask against canonical DMA addresses Suzuki K Poulose
2026-01-20 11:59   ` Robin Murphy
2026-01-20 14:25     ` Aneesh Kumar K.V
2026-01-20 19:22       ` Robin Murphy
2026-01-21  4:50         ` Aneesh Kumar K.V [this message]
2026-01-20 14:18   ` Aneesh Kumar K.V
2026-01-20 14:39     ` Suzuki K Poulose
2026-01-20 15:11       ` Jason Gunthorpe
2026-01-20 17:11         ` Robin Murphy
2026-01-20 17:54           ` Jason Gunthorpe
2026-01-20 18:47             ` Robin Murphy
2026-01-20 19:54               ` Jason Gunthorpe
2026-01-20 10:59 ` kernel test robot
2026-01-20 13:26 ` Jason Gunthorpe
2026-01-20 15:25   ` Aneesh Kumar K.V
2026-01-20 15:43     ` Jason Gunthorpe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=yq5ajyxbk1qv.fsf@kernel.org \
    --to=aneesh.kumar@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@ziepe.ca \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=robin.murphy@arm.com \
    --cc=steven.price@arm.com \
    --cc=suzuki.poulose@arm.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.