From: "Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org>
To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, iommu@lists.linux.dev
Cc: "Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Catalin Marinas <catalin.marinas@arm.com>,
christian.koenig@amd.com, Jason Gunthorpe <jgg@ziepe.ca>,
Joerg Roedel <joro@8bytes.org>, Marc Zyngier <maz@kernel.org>,
Marek Szyprowski <m.szyprowski@samsung.com>,
Robin Murphy <robin.murphy@arm.com>,
Steven Price <steven.price@arm.com>,
Sumit Semwal <sumit.semwal@linaro.org>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Thomas Gleixner <tglx@kernel.org>, Will Deacon <will@kernel.org>,
dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org,
linux-media@vger.kernel.org, linux-mm@kvack.org
Subject: [RFC PATCH v7 06/13] dma-contiguous: Accept an explicit minimum alignment
Date: Mon, 21 Sep 2026 20:18:40 +0530 [thread overview]
Message-ID: <20260921144847.501151-7-aneesh.kumar@kernel.org> (raw)
In-Reply-To: <20260921144847.501151-1-aneesh.kumar@kernel.org>
Confidential-computing shared allocations need CMA backing allocations
to be aligned to the architecture private/shared state-change granule
size. Passing a DMA attribute into CMA would make a generic physical
allocator interpret DMA and confidential-computing policy that has
already been resolved by its caller.
Add an explicit minimum alignment order to dma_alloc_contiguous().
Preserve the existing size-derived alignment for ordinary callers by
passing zero, and reject a request that exceeds CONFIG_CMA_ALIGNMENT.
For supported requests, use the larger of the size-derived and requested
orders, capped by the configured CMA alignment as before.
Also distinguish preferred and required alignment for
dma_alloc_from_contiguous(). Existing callers pass zero as the required
alignment and retain the current clamping behavior. Callers that require
a minimum alignment can request it explicitly and receive NULL when CMA
cannot satisfy it.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
arch/arm/mm/dma-mapping.c | 5 +++--
drivers/iommu/dma-iommu.c | 2 +-
include/linux/dma-map-ops.h | 10 ++++++----
kernel/dma/contiguous.c | 33 +++++++++++++++++++++++----------
kernel/dma/direct.c | 2 +-
kernel/dma/ops_helpers.c | 2 +-
kernel/dma/pool.c | 2 +-
kernel/kexec_file.c | 3 ++-
8 files changed, 38 insertions(+), 21 deletions(-)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 7761099dde9e..9714fcd51941 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -398,7 +398,8 @@ static void *__alloc_from_contiguous(struct device *dev, size_t size,
struct page *page;
void *ptr = NULL;
- page = dma_alloc_from_contiguous(dev, count, order, gfp & __GFP_NOWARN);
+ page = dma_alloc_from_contiguous(dev, count, order, 0,
+ gfp & __GFP_NOWARN);
if (!page)
return NULL;
@@ -866,7 +867,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
unsigned long order = get_order(size);
struct page *page;
- page = dma_alloc_from_contiguous(dev, count, order,
+ page = dma_alloc_from_contiguous(dev, count, order, 0,
gfp & __GFP_NOWARN);
if (!page)
goto error;
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 58c624513cd4..59baf2687612 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -1627,7 +1627,7 @@ static void *iommu_dma_alloc_pages(struct device *dev, size_t size,
struct page *page = NULL;
void *cpu_addr;
- page = dma_alloc_contiguous(dev, alloc_size, gfp);
+ page = dma_alloc_contiguous(dev, alloc_size, gfp, 0);
if (!page)
page = alloc_pages_node(node, gfp, get_order(alloc_size));
if (!page)
diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
index 8fae2b7deb20..5fccda7e5c69 100644
--- a/include/linux/dma-map-ops.h
+++ b/include/linux/dma-map-ops.h
@@ -99,10 +99,11 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
phys_addr_t limit, struct cma **res_cma, bool fixed);
struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
- unsigned int order, bool no_warn);
+ unsigned int order, unsigned int required_order, bool no_warn);
bool dma_release_from_contiguous(struct device *dev, struct page *pages,
int count);
-struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp);
+struct page *dma_alloc_contiguous(struct device *dev, size_t size,
+ gfp_t gfp, unsigned int align_order);
void dma_free_contiguous(struct device *dev, struct page *page, size_t size);
void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size);
@@ -125,7 +126,8 @@ static inline int dma_contiguous_reserve_area(phys_addr_t size,
return -ENOSYS;
}
static inline struct page *dma_alloc_from_contiguous(struct device *dev,
- size_t count, unsigned int order, bool no_warn)
+ size_t count, unsigned int order, unsigned int required_order,
+ bool no_warn)
{
return NULL;
}
@@ -136,7 +138,7 @@ static inline bool dma_release_from_contiguous(struct device *dev,
}
/* Use fallback alloc() and free() when CONFIG_DMA_CMA=n */
static inline struct page *dma_alloc_contiguous(struct device *dev, size_t size,
- gfp_t gfp)
+ gfp_t gfp, unsigned int align_order)
{
return NULL;
}
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
index 66093460584e..a3eb3299b817 100644
--- a/kernel/dma/contiguous.c
+++ b/kernel/dma/contiguous.c
@@ -357,19 +357,25 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
* dma_alloc_from_contiguous() - allocate pages from contiguous area
* @dev: Pointer to device for which the allocation is performed.
* @count: Requested number of pages.
- * @align: Requested alignment of pages (in PAGE_SIZE order).
+ * @align: Preferred alignment of pages (in PAGE_SIZE order).
+ * @required_align: Minimum required alignment (in PAGE_SIZE order).
* @no_warn: Avoid printing message about failed allocation.
*
* This function allocates memory buffer for specified device. It uses
* device specific contiguous memory area if available or the default
* global one. Requires architecture specific dev_get_cma_area() helper
* function.
+ *
+ * The preferred alignment is capped at CONFIG_CMA_ALIGNMENT. Return NULL
+ * if the required alignment exceeds this limit. A required alignment of
+ * zero preserves the preferred-alignment clamping behavior.
*/
struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
- unsigned int align, bool no_warn)
+ unsigned int align, unsigned int required_align, bool no_warn)
{
- if (align > CONFIG_CMA_ALIGNMENT)
- align = CONFIG_CMA_ALIGNMENT;
+ if (required_align > CONFIG_CMA_ALIGNMENT)
+ return NULL;
+ align = min(max(align, required_align), CONFIG_CMA_ALIGNMENT);
return cma_alloc(dev_get_cma_area(dev), count, align, no_warn);
}
@@ -390,9 +396,14 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
return cma_release(dev_get_cma_area(dev), pages, count);
}
-static struct page *cma_alloc_aligned(struct cma *cma, size_t size, gfp_t gfp)
+static struct page *cma_alloc_aligned(struct cma *cma, size_t size,
+ gfp_t gfp, unsigned int align_order)
{
- unsigned int align = min(get_order(size), CONFIG_CMA_ALIGNMENT);
+ unsigned int align;
+
+ if (align_order > CONFIG_CMA_ALIGNMENT)
+ return NULL;
+ align = min(max(get_order(size), align_order), CONFIG_CMA_ALIGNMENT);
return cma_alloc(cma, size >> PAGE_SHIFT, align, gfp & __GFP_NOWARN);
}
@@ -402,6 +413,7 @@ static struct page *cma_alloc_aligned(struct cma *cma, size_t size, gfp_t gfp)
* @dev: Pointer to device for which the allocation is performed.
* @size: Requested allocation size.
* @gfp: Allocation flags.
+ * @align_order: Minimum alignment as a power-of-two page order.
*
* tries to use device specific contiguous memory area if available, or it
* tries to use per-numa cma, if the allocation fails, it will fallback to
@@ -412,7 +424,8 @@ static struct page *cma_alloc_aligned(struct cma *cma, size_t size, gfp_t gfp)
* there is no need to waste CMA pages for that kind; it also helps reduce
* fragmentations.
*/
-struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp)
+struct page *dma_alloc_contiguous(struct device *dev, size_t size,
+ gfp_t gfp, unsigned int align_order)
{
#ifdef CONFIG_DMA_NUMA_CMA
int nid = dev_to_node(dev);
@@ -422,7 +435,7 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp)
if (!gfpflags_allow_blocking(gfp))
return NULL;
if (dev->cma_area)
- return cma_alloc_aligned(dev->cma_area, size, gfp);
+ return cma_alloc_aligned(dev->cma_area, size, gfp, align_order);
if (size <= PAGE_SIZE)
return NULL;
@@ -431,7 +444,7 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp)
struct cma *cma = dma_contiguous_numa_area[nid];
struct page *page;
if (cma) {
- page = cma_alloc_aligned(cma, size, gfp);
+ page = cma_alloc_aligned(cma, size, gfp, align_order);
if (page)
return page;
}
@@ -440,7 +453,7 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp)
if (!dma_contiguous_default_area)
return NULL;
- return cma_alloc_aligned(dma_contiguous_default_area, size, gfp);
+ return cma_alloc_aligned(dma_contiguous_default_area, size, gfp, align_order);
}
/**
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index da665ca22d5c..d968a0c81e73 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -124,7 +124,7 @@ static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
WARN_ON_ONCE(!PAGE_ALIGNED(size));
gfp |= dma_direct_optimal_gfp_mask(dev, &phys_limit);
- page = dma_alloc_contiguous(dev, size, gfp);
+ page = dma_alloc_contiguous(dev, size, gfp, 0);
if (page) {
if (dma_coherent_ok(dev, page_to_phys(page), size) &&
(allow_highmem || !PageHighMem(page)))
diff --git a/kernel/dma/ops_helpers.c b/kernel/dma/ops_helpers.c
index 6b5f9208d31c..8320cc0fada5 100644
--- a/kernel/dma/ops_helpers.c
+++ b/kernel/dma/ops_helpers.c
@@ -66,7 +66,7 @@ struct page *dma_common_alloc_pages(struct device *dev, size_t size,
struct page *page;
phys_addr_t phys;
- page = dma_alloc_contiguous(dev, size, gfp);
+ page = dma_alloc_contiguous(dev, size, gfp, 0);
if (!page)
page = alloc_pages_node(dev_to_node(dev), gfp, get_order(size));
if (!page)
diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
index 00f422a1e896..70b7f64b17ab 100644
--- a/kernel/dma/pool.c
+++ b/kernel/dma/pool.c
@@ -99,7 +99,7 @@ static int atomic_pool_expand(struct dma_gen_pool *dma_pool, size_t pool_size,
pool_size = 1 << (PAGE_SHIFT + order);
if (cma_in_zone(gfp))
page = dma_alloc_from_contiguous(NULL, 1 << order,
- order, false);
+ order, 0, false);
if (!page)
page = alloc_pages(gfp | __GFP_NOWARN, order);
} while (!page && order-- > 0);
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 59fb9d71e9d8..2a337ce7264e 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -682,7 +682,8 @@ static int kexec_alloc_contig(struct kexec_buf *kbuf)
if (kbuf->image->type == KEXEC_TYPE_CRASH)
return -EPERM;
- p = dma_alloc_from_contiguous(NULL, nr_pages, get_order(kbuf->buf_align), true);
+ p = dma_alloc_from_contiguous(NULL, nr_pages,
+ get_order(kbuf->buf_align), 0, true);
if (!p)
return -ENOMEM;
--
2.43.0
next prev parent reply other threads:[~2026-09-21 14:49 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-21 14:48 [RFC PATCH v7 00/13] coco: guest: Add a shared-granule allocator for host-shared memory Aneesh Kumar K.V (Arm)
2026-09-21 14:48 ` [RFC PATCH v7 01/13] arm64: realm: Add RHI helper to query IPA state change alignment Aneesh Kumar K.V (Arm)
2026-09-21 14:48 ` [RFC PATCH v7 02/13] mm: Add an allocator for CoCo shared memory Aneesh Kumar K.V (Arm)
2026-09-22 16:25 ` Catalin Marinas
2026-09-22 16:51 ` Jason Gunthorpe
2026-09-23 0:33 ` Suzuki K Poulose
2026-09-23 5:53 ` Aneesh Kumar K.V
2026-09-23 8:31 ` Aneesh Kumar K.V
2026-09-23 10:10 ` Catalin Marinas
2026-09-23 9:42 ` Catalin Marinas
2026-09-23 9:59 ` Aneesh Kumar K.V
2026-09-23 10:28 ` Aneesh Kumar K.V
2026-09-23 10:40 ` Catalin Marinas
2026-09-23 13:06 ` Jason Gunthorpe
2026-09-23 14:58 ` Aneesh Kumar K.V
2026-09-23 15:11 ` Suzuki K Poulose
2026-09-23 15:21 ` Jason Gunthorpe
2026-09-23 16:28 ` Kameron Carr
2026-09-23 17:23 ` Jason Gunthorpe
2026-09-23 18:36 ` Michael Kelley
2026-09-23 13:00 ` Jason Gunthorpe
2026-09-23 15:20 ` Mostafa Saleh
2026-09-21 14:48 ` [RFC PATCH v7 03/13] arm64: realm: Expose the CCA shared granule size through mem_encrypt ops Aneesh Kumar K.V (Arm)
2026-09-21 14:48 ` [RFC PATCH v7 04/13] irqchip/gic-v3-its: Resolve the default NUMA node explicitly Aneesh Kumar K.V (Arm)
2026-09-21 14:48 ` [RFC PATCH v7 05/13] irqchip/gic-v3-its: Allocate shared tables using CoCo shared memory allocator Aneesh Kumar K.V (Arm)
2026-09-21 14:48 ` Aneesh Kumar K.V (Arm) [this message]
2026-09-23 10:35 ` [RFC PATCH v7 06/13] dma-contiguous: Accept an explicit minimum alignment Catalin Marinas
2026-09-23 11:49 ` Aneesh Kumar K.V
2026-09-23 13:49 ` Catalin Marinas
2026-09-21 14:48 ` [RFC PATCH v7 07/13] dma-pool: Allocate CoCo atomic pools using CoCo shared memory allocator Aneesh Kumar K.V (Arm)
2026-09-21 14:48 ` [RFC PATCH v7 08/13] dma-direct: Align CoCo shared DMA allocations to the shared granule size Aneesh Kumar K.V (Arm)
2026-09-21 14:48 ` [RFC PATCH v7 09/13] swiotlb: Align shared IO TLB pools " Aneesh Kumar K.V (Arm)
2026-09-21 14:48 ` [RFC PATCH v7 10/13] swiotlb: Reject misaligned restricted DMA pools for CoCo guests Aneesh Kumar K.V (Arm)
2026-09-21 14:48 ` [RFC PATCH v7 11/13] dma-buf: system_heap: Limit scatterlist entries to the buffer size Aneesh Kumar K.V (Arm)
2026-09-21 14:48 ` [RFC PATCH v7 12/13] dma-buf: system_heap: Allocate shared buffers using CoCo shared memory allocator Aneesh Kumar K.V (Arm)
2026-09-22 16:39 ` Catalin Marinas
2026-09-23 8:32 ` Aneesh Kumar K.V
2026-09-23 8:46 ` Christian König
2026-09-21 14:48 ` [RFC PATCH v7 13/13] swiotlb: Make rounded shared pool capacity allocatable Aneesh Kumar K.V (Arm)
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=20260921144847.501151-7-aneesh.kumar@kernel.org \
--to=aneesh.kumar@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=catalin.marinas@arm.com \
--cc=christian.koenig@amd.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=iommu@lists.linux.dev \
--cc=jgg@ziepe.ca \
--cc=joro@8bytes.org \
--cc=kvmarm@lists.linux.dev \
--cc=linaro-mm-sig@lists.linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=m.szyprowski@samsung.com \
--cc=maz@kernel.org \
--cc=robin.murphy@arm.com \
--cc=steven.price@arm.com \
--cc=sumit.semwal@linaro.org \
--cc=suzuki.poulose@arm.com \
--cc=tglx@kernel.org \
--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.