Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
To: Catalin Marinas <catalin.marinas@arm.com>
Cc: iommu@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-coco@lists.linux.dev,
	Robin Murphy <robin.murphy@arm.com>,
	Marek Szyprowski <m.szyprowski@samsung.com>,
	Will Deacon <will@kernel.org>, Marc Zyngier <maz@kernel.org>,
	Steven Price <steven.price@arm.com>,
	Suzuki K Poulose <Suzuki.Poulose@arm.com>,
	Jiri Pirko <jiri@resnulli.us>, Jason Gunthorpe <jgg@ziepe.ca>,
	Mostafa Saleh <smostafa@google.com>,
	Petr Tesarik <ptesarik@suse.com>,
	Alexey Kardashevskiy <aik@amd.com>,
	Dan Williams <dan.j.williams@intel.com>,
	Xu Yilun <yilun.xu@linux.intel.com>,
	linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org,
	Madhavan Srinivasan <maddy@linux.ibm.com>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Nicholas Piggin <npiggin@gmail.com>,
	"Christophe Leroy (CS GROUP)" <chleroy@kernel.org>,
	Alexander Gordeev <agordeev@linux.ibm.com>,
	Gerald Schaefer <gerald.schaefer@linux.ibm.com>,
	Heiko Carstens <hca@linux.ibm.com>,
	Vasily Gorbik <gor@linux.ibm.com>,
	Christian Borntraeger <borntraeger@linux.ibm.com>,
	Sven Schnelle <svens@linux.ibm.com>,
	x86@kernel.org, Jiri Pirko <jiri@nvidia.com>,
	Michael Kelley <mhklinux@outlook.com>
Subject: Re: [PATCH v7 16/22] dma-direct: make dma_direct_map_phys() honor DMA_ATTR_CC_SHARED
Date: Wed, 08 Jul 2026 20:39:04 +0530	[thread overview]
Message-ID: <yq5ase5th627.fsf@kernel.org> (raw)
In-Reply-To: <ak42F240d-53QeFN@arm.com>

Catalin Marinas <catalin.marinas@arm.com> writes:

> On Wed, Jul 01, 2026 at 11:19:20AM +0530, Aneesh Kumar K.V (Arm) wrote:
>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> index 97987f850a33..acf67c7064db 100644
>> --- a/arch/arm64/mm/init.c
>> +++ b/arch/arm64/mm/init.c
>> @@ -338,10 +338,8 @@ void __init arch_mm_preinit(void)
>>  	unsigned int flags = SWIOTLB_VERBOSE;
>>  	bool swiotlb = max_pfn > PFN_DOWN(arm64_dma_phys_limit);
>>  
>> -	if (is_realm_world()) {
>> +	if (is_realm_world())
>>  		swiotlb = true;
>> -		flags |= SWIOTLB_FORCE;
>> -	}
>
> For this part:
>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>
>> diff --git a/kernel/dma/direct.h b/kernel/dma/direct.h
>> index e05dc7649366..f3fc28f352ba 100644
>> --- a/kernel/dma/direct.h
>> +++ b/kernel/dma/direct.h
>> @@ -88,37 +88,40 @@ static inline dma_addr_t dma_direct_map_phys(struct device *dev,
>>  {
>>  	dma_addr_t dma_addr;
>>  
>> +	/*
>> +	 * For a device requiring unencrypted DMA, MMIO memory is treated
>> +	 * as shared by default.
>> +	 */
>> +	if (force_dma_unencrypted(dev) && (attrs & DMA_ATTR_MMIO))
>> +		attrs |= DMA_ATTR_CC_SHARED;
>> +
>>  	if (is_swiotlb_force_bounce(dev)) {
>> -		if (!(attrs & DMA_ATTR_CC_SHARED)) {
>> -			if (attrs & (DMA_ATTR_MMIO | DMA_ATTR_REQUIRE_COHERENT))
>> -				return DMA_MAPPING_ERROR;
>> +		if (attrs & (DMA_ATTR_MMIO | DMA_ATTR_REQUIRE_COHERENT))
>> +			return DMA_MAPPING_ERROR;
>>  
>> -			return swiotlb_map(dev, phys, size, dir, attrs);
>> -		}
>> -	} else if (attrs & DMA_ATTR_CC_SHARED) {
>> -		return DMA_MAPPING_ERROR;
>> +		return swiotlb_map(dev, phys, size, dir, attrs);
>>  	}
>>  
>> -	if (attrs & DMA_ATTR_MMIO) {
>> -		dma_addr = phys;
>> -		if (unlikely(!dma_capable(dev, dma_addr, size, false, attrs)))
>> -			goto err_overflow;
>> -	} else if (attrs & DMA_ATTR_CC_SHARED) {
>> +	if (attrs & DMA_ATTR_CC_SHARED)
>>  		dma_addr = phys_to_dma_unencrypted(dev, phys);
>> +	else
>> +		dma_addr = phys_to_dma_encrypted(dev, phys);
>
> For AMD/SME, on host with memory encryption we now end up setting the C
> bit for DMA_ATTR_MMIO. This is fine for RAM but not sure whether
> some other MMIO bus understands this attribute. Maybe we should stick to
> something like __phys_to_dma() for the !CC_SHARED && MMIO path. Or,
> since this is not universally defined, just use the old dma_addr = phys
> if MMIO and ignore any unlikely DMA offsets.
>
> In the other case, for an arm CCA guest, if the MMIO is shared we end up
> setting the shared attribute but that's fine, it's only an IPA address.
>

P2PDMA with CoCo is currently not supported, as discussed here:

https://lore.kernel.org/all/20260521175420.GA7702@ziepe.ca
https://lore.kernel.org/all/20260522132240.GD7702@ziepe.ca

Since I do not have much experience with P2PDMA, I have prepared a patch
that Leon Romanovsky <leonro@nvidia.com> has kindly agreed to review to
ensure it is correct. I have attached it below.

The conclusion is that P2P is not currently supported, so we get this
series merged first and handle P2PDMA support as a follow-up outside
this series.

commit f39bcb603c5cc4cfa738597715828ac45f01f142
Author: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
Date:   Fri May 22 10:10:35 2026 +0530

    PCI/P2PDMA: Carry host bridge DMA attrs through map and unmap
    
    P2PDMA host bridge mappings currently pass DMA_ATTR_MMIO and rely on
    dma-direct to add DMA_ATTR_CC_SHARED for devices that require unencrypted
    DMA. That puts P2PDMA-specific confidential-computing policy in the generic
    dma-direct MMIO mapping path and does not preserve the selected attributes
    through all unmap paths.
    
    Add DMA mapping flags to struct p2pdma_provider for host bridge mappings
    and use those flags in the block, dma-buf and HMM mapping paths. Store the
    attributes selected at map time where the unmap side no longer has provider
    context, so that the unmap path uses the same attributes that were used for
    mapping.

diff --git a/block/blk-mq-dma.c b/block/blk-mq-dma.c
index bfdb9ed70741..fafc6d6b8522 100644
--- a/block/blk-mq-dma.c
+++ b/block/blk-mq-dma.c
@@ -87,10 +87,11 @@ static bool blk_dma_map_bus(struct blk_dma_iter *iter, struct phys_vec *vec)
 static bool blk_dma_map_direct(struct request *req, struct device *dma_dev,
 		struct blk_dma_iter *iter, struct phys_vec *vec)
 {
-	unsigned int attrs = 0;
+	unsigned long attrs = 0;
 
 	if (iter->p2pdma.map == PCI_P2PDMA_MAP_THRU_HOST_BRIDGE)
-		attrs |= DMA_ATTR_MMIO;
+		attrs |= iter->p2pdma.mem->dma_mapping_flags;
+	iter->attrs = attrs;
 
 	iter->addr = dma_map_phys(dma_dev, vec->paddr, vec->len,
 			rq_dma_dir(req), attrs);
@@ -107,7 +108,7 @@ static bool blk_rq_dma_map_iova(struct request *req, struct device *dma_dev,
 		struct phys_vec *vec)
 {
 	enum dma_data_direction dir = rq_dma_dir(req);
-	unsigned int attrs = 0;
+	unsigned long attrs = 0;
 	size_t mapped = 0;
 	int error;
 
@@ -115,7 +116,8 @@ static bool blk_rq_dma_map_iova(struct request *req, struct device *dma_dev,
 	iter->len = dma_iova_size(state);
 
 	if (iter->p2pdma.map == PCI_P2PDMA_MAP_THRU_HOST_BRIDGE)
-		attrs |= DMA_ATTR_MMIO;
+		attrs |= iter->p2pdma.mem->dma_mapping_flags;
+	iter->attrs = attrs;
 
 	do {
 		error = dma_iova_link(dma_dev, state, vec->paddr, mapped,
@@ -168,6 +170,7 @@ static bool blk_dma_map_iter_start(struct request *req, struct device *dma_dev,
 	struct phys_vec vec;
 
 	memset(&iter->p2pdma, 0, sizeof(iter->p2pdma));
+	iter->attrs = 0;
 	iter->status = BLK_STS_OK;
 	iter->p2pdma.map = PCI_P2PDMA_MAP_NONE;
 
diff --git a/drivers/dma-buf/dma-buf-mapping.c b/drivers/dma-buf/dma-buf-mapping.c
index 794acff2546a..e6d4ee8acd19 100644
--- a/drivers/dma-buf/dma-buf-mapping.c
+++ b/drivers/dma-buf/dma-buf-mapping.c
@@ -59,11 +59,13 @@ static unsigned int calc_sg_nents(struct dma_iova_state *state,
  * @sgt:    Scatter-gather table
  * @state:  DMA IOVA state relevant in IOMMU-based DMA
  * @size:   Total size of DMA transfer
+ * @attrs:  DMA attributes used for host bridge mappings
  */
 struct dma_buf_dma {
 	struct sg_table sgt;
 	struct dma_iova_state *state;
 	size_t size;
+	unsigned long attrs;
 };
 
 /**
@@ -119,6 +121,7 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 		 */
 		break;
 	case PCI_P2PDMA_MAP_THRU_HOST_BRIDGE:
+		dma->attrs = provider->dma_mapping_flags;
 		dma->state = kzalloc_obj(*dma->state);
 		if (!dma->state) {
 			ret = -ENOMEM;
@@ -147,7 +150,7 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 			ret = dma_iova_link(attach->dev, dma->state,
 					    phys_vec[i].paddr, 0,
 					    phys_vec[i].len, dir,
-					    DMA_ATTR_MMIO);
+					    dma->attrs);
 			if (ret)
 				goto err_unmap_dma;
 
@@ -155,7 +158,7 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 		} else {
 			addr = dma_map_phys(attach->dev, phys_vec[i].paddr,
 					    phys_vec[i].len, dir,
-					    DMA_ATTR_MMIO);
+					    dma->attrs);
 			ret = dma_mapping_error(attach->dev, addr);
 			if (ret)
 				goto err_unmap_dma;
@@ -195,11 +198,11 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 		; /* Do nothing */
 	} else if (dma_use_iova(dma->state)) {
 		dma_iova_destroy(attach->dev, dma->state, mapped_len, dir,
-				 DMA_ATTR_MMIO);
+				 dma->attrs);
 	} else {
 		for_each_sgtable_dma_sg(&dma->sgt, sgl, i)
 			dma_unmap_phys(attach->dev, sg_dma_address(sgl),
-				       sg_dma_len(sgl), dir, DMA_ATTR_MMIO);
+				       sg_dma_len(sgl), dir, dma->attrs);
 	}
 	sg_free_table(&dma->sgt);
 err_free_state:
@@ -231,13 +234,13 @@ void dma_buf_free_sgt(struct dma_buf_attachment *attach, struct sg_table *sgt,
 		; /* Do nothing */
 	} else if (dma_use_iova(dma->state)) {
 		dma_iova_destroy(attach->dev, dma->state, dma->size, dir,
-				 DMA_ATTR_MMIO);
+				 dma->attrs);
 	} else {
 		struct scatterlist *sgl;
 
 		for_each_sgtable_dma_sg(sgt, sgl, i)
 			dma_unmap_phys(attach->dev, sg_dma_address(sgl),
-				       sg_dma_len(sgl), dir, DMA_ATTR_MMIO);
+				       sg_dma_len(sgl), dir, dma->attrs);
 	}
 
 	sg_free_table(sgt);
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 69932d640b53..8f05f53b78fd 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -436,6 +436,7 @@ struct nvme_iod {
 
 	size_t total_len;
 	struct dma_iova_state dma_state;
+	unsigned long dma_attrs;
 	void *descriptors[NVME_MAX_NR_DESCRIPTORS];
 	struct nvme_dma_vec *dma_vecs;
 	unsigned int nr_dma_vecs;
@@ -443,6 +444,7 @@ struct nvme_iod {
 	dma_addr_t meta_dma;
 	size_t meta_total_len;
 	struct dma_iova_state meta_dma_state;
+	unsigned long meta_dma_attrs;
 	struct nvme_sgl_desc *meta_descriptor;
 };
 
@@ -859,7 +861,7 @@ static void nvme_free_descriptors(struct request *req)
 	}
 }
 
-static void nvme_free_prps(struct request *req, unsigned int attrs)
+static void nvme_free_prps(struct request *req, unsigned long attrs)
 {
 	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
 	struct nvme_queue *nvmeq = req->mq_hctx->driver_data;
@@ -872,7 +874,7 @@ static void nvme_free_prps(struct request *req, unsigned int attrs)
 }
 
 static void nvme_free_sgls(struct request *req, struct nvme_sgl_desc *sge,
-		struct nvme_sgl_desc *sg_list, unsigned int attrs)
+		struct nvme_sgl_desc *sg_list, unsigned long attrs)
 {
 	struct nvme_queue *nvmeq = req->mq_hctx->driver_data;
 	enum dma_data_direction dir = rq_dma_dir(req);
@@ -899,7 +901,7 @@ static void nvme_unmap_metadata(struct request *req)
 	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
 	struct device *dma_dev = nvmeq->dev->dev;
 	struct nvme_sgl_desc *sge = iod->meta_descriptor;
-	unsigned int attrs = 0;
+	unsigned long attrs = 0;
 
 	if (iod->flags & IOD_SINGLE_META_SEGMENT) {
 		dma_unmap_page(dma_dev, iod->meta_dma,
@@ -912,11 +914,11 @@ static void nvme_unmap_metadata(struct request *req)
 		map = PCI_P2PDMA_MAP_BUS_ADDR;
 	else if (iod->flags & IOD_META_MMIO) {
 		map = PCI_P2PDMA_MAP_THRU_HOST_BRIDGE;
-		attrs |= DMA_ATTR_MMIO;
+		attrs = iod->meta_dma_attrs;
 	}
 
 	if (!blk_rq_dma_unmap(req, dma_dev, &iod->meta_dma_state,
-			      iod->meta_total_len, map)) {
+			      iod->meta_total_len, map, attrs)) {
 		if (nvme_pci_cmd_use_meta_sgl(&iod->cmd))
 			nvme_free_sgls(req, sge, &sge[1], attrs);
 		else
@@ -935,7 +937,7 @@ static void nvme_unmap_data(struct request *req)
 	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
 	struct nvme_queue *nvmeq = req->mq_hctx->driver_data;
 	struct device *dma_dev = nvmeq->dev->dev;
-	unsigned int attrs = 0;
+	unsigned long attrs = 0;
 
 	if (iod->flags & IOD_SINGLE_SEGMENT) {
 		static_assert(offsetof(union nvme_data_ptr, prp1) ==
@@ -949,11 +951,11 @@ static void nvme_unmap_data(struct request *req)
 		map = PCI_P2PDMA_MAP_BUS_ADDR;
 	else if (iod->flags & IOD_DATA_MMIO) {
 		map = PCI_P2PDMA_MAP_THRU_HOST_BRIDGE;
-		attrs |= DMA_ATTR_MMIO;
+		attrs = iod->dma_attrs;
 	}
 
 	if (!blk_rq_dma_unmap(req, dma_dev, &iod->dma_state, iod->total_len,
-			      map)) {
+			      map, attrs)) {
 		if (nvme_pci_cmd_use_sgl(&iod->cmd))
 			nvme_free_sgls(req, &iod->cmd.common.dptr.sgl,
 			               iod->descriptors[0], attrs);
@@ -1270,6 +1272,7 @@ static blk_status_t nvme_map_data(struct request *req)
 		break;
 	case PCI_P2PDMA_MAP_THRU_HOST_BRIDGE:
 		iod->flags |= IOD_DATA_MMIO;
+		iod->dma_attrs = iter.attrs;
 		break;
 	case PCI_P2PDMA_MAP_NONE:
 		break;
@@ -1305,6 +1308,7 @@ static blk_status_t nvme_pci_setup_meta_iter(struct request *req)
 		break;
 	case PCI_P2PDMA_MAP_THRU_HOST_BRIDGE:
 		iod->flags |= IOD_META_MMIO;
+		iod->meta_dma_attrs = iter.attrs;
 		break;
 	case PCI_P2PDMA_MAP_NONE:
 		break;
@@ -1405,6 +1409,8 @@ static blk_status_t nvme_prep_rq(struct request *req)
 	iod->nr_descriptors = 0;
 	iod->total_len = 0;
 	iod->meta_total_len = 0;
+	iod->dma_attrs = 0;
+	iod->meta_dma_attrs = 0;
 	iod->nr_dma_vecs = 0;
 
 	ret = nvme_setup_cmd(req->q->queuedata, req);
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index b2d5266f8653..35ab3f8b53a8 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -285,6 +285,11 @@ int pcim_p2pdma_init(struct pci_dev *pdev)
 			continue;
 
 		p2p->mem[i].owner = &pdev->dev;
+
+		p2p->mem[i].dma_mapping_flags = DMA_ATTR_MMIO;
+		if (force_dma_unencrypted(dev))
+			p2p->mem[i].dma_mapping_flags |= DMA_ATTR_CC_SHARED;
+
 		p2p->mem[i].bus_offset =
 			pci_bus_address(pdev, i) - pci_resource_start(pdev, i);
 	}
diff --git a/include/linux/blk-mq-dma.h b/include/linux/blk-mq-dma.h
index 214c181ff2c9..fab72c0f8053 100644
--- a/include/linux/blk-mq-dma.h
+++ b/include/linux/blk-mq-dma.h
@@ -16,6 +16,7 @@ struct blk_dma_iter {
 	/* Output address range for this iteration */
 	dma_addr_t			addr;
 	u32				len;
+	unsigned long			attrs;
 	struct pci_p2pdma_map_state	p2pdma;
 
 	/* Status code. Only valid when blk_rq_dma_map_iter_* returned false */
@@ -49,23 +50,19 @@ static inline bool blk_rq_dma_map_coalesce(struct dma_iova_state *state)
  * @state:	DMA IOVA state
  * @mapped_len: number of bytes to unmap
  * @map:	peer-to-peer mapping type
+ * @attrs:	DMA attributes used for the mapping
  *
  * Returns %false if the callers need to manually unmap every DMA segment
  * mapped using @iter or %true if no work is left to be done.
  */
 static inline bool blk_rq_dma_unmap(struct request *req, struct device *dma_dev,
 		struct dma_iova_state *state, size_t mapped_len,
-		enum pci_p2pdma_map_type map)
+		enum pci_p2pdma_map_type map, unsigned long attrs)
 {
 	if (map == PCI_P2PDMA_MAP_BUS_ADDR)
 		return true;
 
 	if (dma_use_iova(state)) {
-		unsigned int attrs = 0;
-
-		if (map == PCI_P2PDMA_MAP_THRU_HOST_BRIDGE)
-			attrs |= DMA_ATTR_MMIO;
-
 		dma_iova_destroy(dma_dev, state, mapped_len, rq_dma_dir(req),
 				 attrs);
 		return true;
diff --git a/include/linux/hmm-dma.h b/include/linux/hmm-dma.h
index f58b9fc71999..d9f967ed7ce1 100644
--- a/include/linux/hmm-dma.h
+++ b/include/linux/hmm-dma.h
@@ -14,12 +14,14 @@ struct pci_p2pdma_map_state;
  * @state: DMA IOVA state
  * @pfns: array of PFNs
  * @dma_list: array of DMA addresses
+ * @dma_attrs: array of DMA attributes
  * @dma_entry_size: size of each DMA entry in the array
  */
 struct hmm_dma_map {
 	struct dma_iova_state state;
 	unsigned long *pfn_list;
 	dma_addr_t *dma_list;
+	unsigned long *dma_attrs;
 	size_t dma_entry_size;
 };
 
diff --git a/include/linux/pci-p2pdma.h b/include/linux/pci-p2pdma.h
index 873de20a2247..402dc5e5d62b 100644
--- a/include/linux/pci-p2pdma.h
+++ b/include/linux/pci-p2pdma.h
@@ -21,10 +21,12 @@ struct scatterlist;
  *
  * A p2pdma provider is a range of MMIO address space available to the CPU.
  * @owner: Device to which this provider belongs.
+ * @dma_mapping_flags: DMA attributes to use for host bridge mappings.
  * @bus_offset: Bus offset for p2p communication.
  */
 struct p2pdma_provider {
 	struct device *owner;
+	unsigned long dma_mapping_flags;
 	u64 bus_offset;
 };
 
diff --git a/mm/hmm.c b/mm/hmm.c
index c72c9ddfdb2f..a871d8cb7dd9 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -720,6 +720,11 @@ int hmm_dma_map_alloc(struct device *dev, struct hmm_dma_map *map,
 	if (!map->pfn_list)
 		return -ENOMEM;
 
+	map->dma_attrs = kvcalloc(nr_entries, sizeof(*map->dma_attrs),
+				  GFP_KERNEL | __GFP_NOWARN);
+	if (!map->dma_attrs)
+		goto err_attrs;
+
 	use_iova = dma_iova_try_alloc(dev, &map->state, 0,
 			nr_entries * PAGE_SIZE);
 	if (!use_iova && dma_need_unmap(dev)) {
@@ -731,6 +736,8 @@ int hmm_dma_map_alloc(struct device *dev, struct hmm_dma_map *map,
 	return 0;
 
 err_dma:
+	kvfree(map->dma_attrs);
+err_attrs:
 	kvfree(map->pfn_list);
 	return -ENOMEM;
 }
@@ -749,6 +756,7 @@ void hmm_dma_map_free(struct device *dev, struct hmm_dma_map *map)
 		dma_iova_free(dev, &map->state);
 	kvfree(map->pfn_list);
 	kvfree(map->dma_list);
+	kvfree(map->dma_attrs);
 }
 EXPORT_SYMBOL_GPL(hmm_dma_map_free);
 
@@ -811,11 +819,12 @@ dma_addr_t hmm_dma_map_pfn(struct device *dev, struct hmm_dma_map *map,
 	case PCI_P2PDMA_MAP_NONE:
 		break;
 	case PCI_P2PDMA_MAP_THRU_HOST_BRIDGE:
-		attrs |= DMA_ATTR_MMIO;
+		attrs |= p2pdma_state->mem->dma_mapping_flags;
 		pfns[idx] |= HMM_PFN_P2PDMA;
 		break;
 	case PCI_P2PDMA_MAP_BUS_ADDR:
 		pfns[idx] |= HMM_PFN_P2PDMA_BUS | HMM_PFN_DMA_MAPPED;
+		map->dma_attrs[idx] = 0;
 		return pci_p2pdma_bus_addr_map(p2pdma_state->mem, paddr);
 	default:
 		return DMA_MAPPING_ERROR;
@@ -848,10 +857,12 @@ dma_addr_t hmm_dma_map_pfn(struct device *dev, struct hmm_dma_map *map,
 		if (dma_need_unmap(dev))
 			dma_addrs[idx] = dma_addr;
 	}
+	map->dma_attrs[idx] = attrs;
 	pfns[idx] |= HMM_PFN_DMA_MAPPED;
 	return dma_addr;
 error:
 	pfns[idx] &= ~HMM_PFN_P2PDMA;
+	map->dma_attrs[idx] = 0;
 	return DMA_MAPPING_ERROR;
 
 }
@@ -871,14 +882,11 @@ bool hmm_dma_unmap_pfn(struct device *dev, struct hmm_dma_map *map, size_t idx)
 	struct dma_iova_state *state = &map->state;
 	dma_addr_t *dma_addrs = map->dma_list;
 	unsigned long *pfns = map->pfn_list;
-	unsigned long attrs = DMA_ATTR_REQUIRE_COHERENT;
+	unsigned long attrs = DMA_ATTR_REQUIRE_COHERENT | map->dma_attrs[idx];
 
 	if ((pfns[idx] & valid_dma) != valid_dma)
 		return false;
 
-	if (pfns[idx] & HMM_PFN_P2PDMA)
-		attrs |= DMA_ATTR_MMIO;
-
 	if (pfns[idx] & HMM_PFN_P2PDMA_BUS)
 		; /* no need to unmap bus address P2P mappings */
 	else if (dma_use_iova(state))
@@ -890,6 +898,7 @@ bool hmm_dma_unmap_pfn(struct device *dev, struct hmm_dma_map *map, size_t idx)
 
 	pfns[idx] &=
 		~(HMM_PFN_DMA_MAPPED | HMM_PFN_P2PDMA | HMM_PFN_P2PDMA_BUS);
+	map->dma_attrs[idx] = 0;
 	return true;
 }
 EXPORT_SYMBOL_GPL(hmm_dma_unmap_pfn);



  reply	other threads:[~2026-07-08 15:09 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-01  5:49 [PATCH v7 00/22] dma-mapping: Track shared DMA state through direct, pool and swiotlb paths Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 01/22] dma-direct: return struct page from dma_direct_alloc_from_pool() Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 02/22] dma-pool: fix page leak in atomic_pool_expand() cleanup Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 03/22] iommu/dma: Check atomic pool allocation result directly Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 04/22] dma: free atomic pool pages by physical address Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 05/22] swiotlb: Preserve allocation virtual address for dynamic pools Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 06/22] s390: Expose protected virtualization through cc_platform_has() Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 07/22] dma-direct: swiotlb: handle swiotlb alloc/free outside __dma_direct_alloc_pages Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 08/22] coco: arm64: s390: powerpc: Mark secure guests with CC_ATTR_GUEST_MEM_ENCRYPT Aneesh Kumar K.V (Arm)
2026-07-07 15:41   ` Suzuki K Poulose
2026-07-07 16:58   ` Catalin Marinas
2026-07-01  5:49 ` [PATCH v7 09/22] dma-mapping: Add internal shared allocation attribute Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 10/22] dma-direct: use __DMA_ATTR_ALLOC_CC_SHARED in alloc/free paths Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 11/22] dma-pool: track decrypted atomic pools and select them via attrs Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 12/22] dma: swiotlb: pass mapping attributes by reference Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 13/22] dma: swiotlb: track pool encryption state and honor DMA_ATTR_CC_SHARED Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 14/22] dma-mapping: make dma_pgprot() honor __DMA_ATTR_ALLOC_CC_SHARED Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 15/22] dma-direct: pass attrs to dma_capable() for DMA_ATTR_CC_SHARED checks Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 16/22] dma-direct: make dma_direct_map_phys() honor DMA_ATTR_CC_SHARED Aneesh Kumar K.V (Arm)
2026-07-08 11:35   ` Catalin Marinas
2026-07-08 15:09     ` Aneesh Kumar K.V [this message]
2026-07-08 17:58     ` Aneesh Kumar K.V
2026-07-09 11:13       ` Catalin Marinas
2026-07-08 12:11   ` Suzuki K Poulose
2026-07-01  5:49 ` [PATCH v7 17/22] dma-direct: set decrypted flag for remapped DMA allocations Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 18/22] dma-direct: select DMA address encoding from __DMA_ATTR_ALLOC_CC_SHARED Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 19/22] dma-direct: rename ret to cpu_addr in alloc helpers Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 20/22] dma: swiotlb: free dynamic pools from process context Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 21/22] dma: swiotlb: handle set_memory_decrypted() failures Aneesh Kumar K.V (Arm)
2026-07-01  5:49 ` [PATCH v7 22/22] swiotlb: remove unused SWIOTLB_FORCE flag Aneesh Kumar K.V (Arm)
2026-07-07  8:06 ` [PATCH v7 00/22] dma-mapping: Track shared DMA state through direct, pool and swiotlb paths Aneesh Kumar K.V
2026-07-07 13:03   ` Marek Szyprowski

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=yq5ase5th627.fsf@kernel.org \
    --to=aneesh.kumar@kernel.org \
    --cc=Suzuki.Poulose@arm.com \
    --cc=agordeev@linux.ibm.com \
    --cc=aik@amd.com \
    --cc=borntraeger@linux.ibm.com \
    --cc=catalin.marinas@arm.com \
    --cc=chleroy@kernel.org \
    --cc=dan.j.williams@intel.com \
    --cc=gerald.schaefer@linux.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@ziepe.ca \
    --cc=jiri@nvidia.com \
    --cc=jiri@resnulli.us \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=m.szyprowski@samsung.com \
    --cc=maddy@linux.ibm.com \
    --cc=maz@kernel.org \
    --cc=mhklinux@outlook.com \
    --cc=mpe@ellerman.id.au \
    --cc=npiggin@gmail.com \
    --cc=ptesarik@suse.com \
    --cc=robin.murphy@arm.com \
    --cc=smostafa@google.com \
    --cc=steven.price@arm.com \
    --cc=svens@linux.ibm.com \
    --cc=will@kernel.org \
    --cc=x86@kernel.org \
    --cc=yilun.xu@linux.intel.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox