* [PATCH v6 1/9] mm/mem_encrypt: Add helpers for shared-buffer alignment
2026-09-04 10:34 [PATCH v6 0/9] coco: guest: Enforce host page-size alignment for shared buffers Aneesh Kumar K.V (Arm)
@ 2026-09-04 10:34 ` Aneesh Kumar K.V (Arm)
2026-09-04 10:34 ` [PATCH v6 2/9] irqchip/gic-v3-its: Align shared ITS allocations to the CoCo shared granule size Aneesh Kumar K.V (Arm)
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 10:34 UTC (permalink / raw)
To: linux-coco, kvmarm, linux-arm-kernel, linux-kernel, iommu
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Jason Gunthorpe,
Marc Zyngier, Marek Szyprowski, Robin Murphy, Steven Price,
Suzuki K Poulose, Thomas Gleixner, Will Deacon
confidential-computing guests may require shared buffers with alignment
larger than the guest page size. As these buffers are shared with the host,
which may manage shared/private state at a different page-size granularity,
the required alignment must account for the host's page size as well.
Add helpers for querying the shared-buffer granule size and for rounding
sizes up to that granule. The generic implementation defaults to PAGE_SIZE
so that existing architectures keep their current behaviour unless they
override the granule size.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
include/linux/mem_encrypt.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/include/linux/mem_encrypt.h b/include/linux/mem_encrypt.h
index 07584c5e36fb..5d2a868f8d3d 100644
--- a/include/linux/mem_encrypt.h
+++ b/include/linux/mem_encrypt.h
@@ -11,6 +11,8 @@
#define __MEM_ENCRYPT_H__
#ifndef __ASSEMBLY__
+#include <linux/align.h>
+#include <vdso/page.h>
#ifdef CONFIG_ARCH_HAS_MEM_ENCRYPT
@@ -54,6 +56,18 @@
#define dma_addr_canonical(x) (x)
#endif
+#ifndef mem_cc_shared_granule_size
+static inline size_t mem_cc_shared_granule_size(void)
+{
+ return PAGE_SIZE;
+}
+#endif
+
+static inline size_t mem_cc_align_to_shared_granule(size_t size)
+{
+ return ALIGN(size, mem_cc_shared_granule_size());
+}
+
#endif /* __ASSEMBLY__ */
#endif /* __MEM_ENCRYPT_H__ */
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v6 2/9] irqchip/gic-v3-its: Align shared ITS allocations to the CoCo shared granule size
2026-09-04 10:34 [PATCH v6 0/9] coco: guest: Enforce host page-size alignment for shared buffers Aneesh Kumar K.V (Arm)
2026-09-04 10:34 ` [PATCH v6 1/9] mm/mem_encrypt: Add helpers for shared-buffer alignment Aneesh Kumar K.V (Arm)
@ 2026-09-04 10:34 ` Aneesh Kumar K.V (Arm)
2026-09-04 10:34 ` [PATCH v6 3/9] dma-mapping: Pass allocation attrs to contiguous allocation helpers Aneesh Kumar K.V (Arm)
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 10:34 UTC (permalink / raw)
To: linux-coco, kvmarm, linux-arm-kernel, linux-kernel, iommu
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Jason Gunthorpe,
Marc Zyngier, Marek Szyprowski, Robin Murphy, Steven Price,
Suzuki K Poulose, Thomas Gleixner, Will Deacon
ITS tables allocated by the coco guest are shared with the hypervisor.
These allocations must satisfy the host shared-buffer granule size so that
the full converted range is safe for host access.
Allocate ITS pages using a size rounded up to the shared granule size and
use the same allocation order when encrypting, decrypting and freeing the
memory. Also grow the ITT cache in shared-granule sized chunks instead of
assuming PAGE_SIZE is sufficient.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
drivers/irqchip/irq-gic-v3-its.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index e9807af23537..98d8fccbf0f2 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -216,6 +216,7 @@ static struct page *its_alloc_pages_node(int node, gfp_t gfp,
struct page *page;
int ret = 0;
+ order = get_order(mem_cc_align_to_shared_granule(PAGE_SIZE << order));
page = alloc_pages_node(node, gfp | gfp_flags_quirk, order);
if (!page)
@@ -241,6 +242,8 @@ static struct page *its_alloc_pages(gfp_t gfp, unsigned int order)
static void its_free_pages(void *addr, unsigned int order)
{
+
+ order = get_order(mem_cc_align_to_shared_granule(PAGE_SIZE << order));
/*
* If the memory cannot be encrypted again then we must leak the pages.
* set_memory_encrypted() will already have WARNed.
@@ -272,7 +275,8 @@ static void *itt_alloc_pool(int node, int size)
if (!page)
break;
- gen_pool_add(itt_pool, (unsigned long)page_address(page), PAGE_SIZE, node);
+ gen_pool_add(itt_pool, (unsigned long)page_address(page),
+ mem_cc_align_to_shared_granule(PAGE_SIZE), node);
} while (!addr);
return (void *)addr;
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v6 3/9] dma-mapping: Pass allocation attrs to contiguous allocation helpers
2026-09-04 10:34 [PATCH v6 0/9] coco: guest: Enforce host page-size alignment for shared buffers Aneesh Kumar K.V (Arm)
2026-09-04 10:34 ` [PATCH v6 1/9] mm/mem_encrypt: Add helpers for shared-buffer alignment Aneesh Kumar K.V (Arm)
2026-09-04 10:34 ` [PATCH v6 2/9] irqchip/gic-v3-its: Align shared ITS allocations to the CoCo shared granule size Aneesh Kumar K.V (Arm)
@ 2026-09-04 10:34 ` Aneesh Kumar K.V (Arm)
2026-09-04 10:34 ` [PATCH v6 4/9] dma-direct: Align CoCo shared DMA allocations to the shared granule size Aneesh Kumar K.V (Arm)
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 10:34 UTC (permalink / raw)
To: linux-coco, kvmarm, linux-arm-kernel, linux-kernel, iommu
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Jason Gunthorpe,
Marc Zyngier, Marek Szyprowski, Robin Murphy, Steven Price,
Suzuki K Poulose, Thomas Gleixner, Will Deacon
Prepare for handling CoCo shared allocation requirements in the common
contiguous allocation path by passing DMA allocation attributes down to the
helpers that may allocate from CMA.
The next patch uses this to apply shared-granule alignment only to
allocations that are actually creating CoCo shared backing pages.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
drivers/iommu/dma-iommu.c | 2 +-
include/linux/dma-map-ops.h | 5 +++--
kernel/dma/contiguous.c | 4 +++-
kernel/dma/direct.c | 11 ++++++-----
kernel/dma/ops_helpers.c | 3 ++-
5 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 58c624513cd4..32ed56aff12a 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, attrs);
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..1849f352fb88 100644
--- a/include/linux/dma-map-ops.h
+++ b/include/linux/dma-map-ops.h
@@ -102,7 +102,8 @@ struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
unsigned int 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 long attrs);
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);
@@ -136,7 +137,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 long attrs)
{
return NULL;
}
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
index 66093460584e..18cd423fbc67 100644
--- a/kernel/dma/contiguous.c
+++ b/kernel/dma/contiguous.c
@@ -402,6 +402,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.
+ * @attrs: DMA attributes.
*
* 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 +413,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 long attrs)
{
#ifdef CONFIG_DMA_NUMA_CMA
int nid = dev_to_node(dev);
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index da665ca22d5c..fe02e8a3c0bb 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -115,7 +115,7 @@ static struct page *dma_direct_alloc_swiotlb(struct device *dev, size_t size,
}
static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
- gfp_t gfp, bool allow_highmem)
+ gfp_t gfp, bool allow_highmem, unsigned long attrs)
{
int node = dev_to_node(dev);
struct page *page;
@@ -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, attrs);
if (page) {
if (dma_coherent_ok(dev, page_to_phys(page), size) &&
(allow_highmem || !PageHighMem(page)))
@@ -184,7 +184,7 @@ static void *dma_direct_alloc_no_mapping(struct device *dev, size_t size,
{
struct page *page;
- page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO, true);
+ page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO, true, 0);
if (!page)
return NULL;
@@ -286,7 +286,8 @@ void *dma_direct_alloc(struct device *dev, size_t size,
}
/* we always manually zero the memory once we are done */
- page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO, allow_highmem);
+ page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO,
+ allow_highmem, attrs);
if (!page)
return NULL;
@@ -452,7 +453,7 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
goto setup_page;
}
- page = __dma_direct_alloc_pages(dev, size, gfp, false);
+ page = __dma_direct_alloc_pages(dev, size, gfp, false, attrs);
if (!page)
return NULL;
diff --git a/kernel/dma/ops_helpers.c b/kernel/dma/ops_helpers.c
index 6b5f9208d31c..43e5f8008a9c 100644
--- a/kernel/dma/ops_helpers.c
+++ b/kernel/dma/ops_helpers.c
@@ -66,7 +66,8 @@ 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);
+ /* __DMA_ATTR_ALLOC_CC_SHARED is not yet supported here, attrs = 0 */
+ page = dma_alloc_contiguous(dev, size, gfp, 0);
if (!page)
page = alloc_pages_node(dev_to_node(dev), gfp, get_order(size));
if (!page)
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v6 4/9] dma-direct: Align CoCo shared DMA allocations to the shared granule size
2026-09-04 10:34 [PATCH v6 0/9] coco: guest: Enforce host page-size alignment for shared buffers Aneesh Kumar K.V (Arm)
` (2 preceding siblings ...)
2026-09-04 10:34 ` [PATCH v6 3/9] dma-mapping: Pass allocation attrs to contiguous allocation helpers Aneesh Kumar K.V (Arm)
@ 2026-09-04 10:34 ` Aneesh Kumar K.V (Arm)
2026-09-04 10:34 ` [PATCH v6 5/9] swiotlb: Align shared IO TLB pools " Aneesh Kumar K.V (Arm)
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 10:34 UTC (permalink / raw)
To: linux-coco, kvmarm, linux-arm-kernel, linux-kernel, iommu
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Jason Gunthorpe,
Marc Zyngier, Marek Szyprowski, Robin Murphy, Steven Price,
Suzuki K Poulose, Thomas Gleixner, Will Deacon
DMA allocations that create shared backing pages for confidential-computing
guests are converted between private and shared memory before being used
for DMA. On some architecture, the conversion granule may be larger than
PAGE_SIZE, so converting only the requested size can leave the rest of the
host-managed granule private.
Use the internal __DMA_ATTR_ALLOC_CC_SHARED allocation attribute to
identify those allocations in the DMA allocation paths. Round the allocated
and converted size up to mem_cc_shared_granule_size(), and use the same
aligned size when restoring encryption on free.
Also reject CMA allocations for CoCo shared backing pages when CMA cannot
provide alignment at the required shared granule size, and keep atomic DMA
pool expansion from falling below the order needed for shared-buffer
conversions.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
kernel/dma/contiguous.c | 9 +++++++++
kernel/dma/direct.c | 16 ++++++++++++++--
kernel/dma/pool.c | 4 +++-
3 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
index 18cd423fbc67..6bdd4f264733 100644
--- a/kernel/dma/contiguous.c
+++ b/kernel/dma/contiguous.c
@@ -45,6 +45,7 @@
#include <linux/dma-map-ops.h>
#include <linux/cma.h>
#include <linux/nospec.h>
+#include <linux/mem_encrypt.h>
#ifdef CONFIG_CMA_SIZE_MBYTES
#define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
@@ -419,6 +420,14 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp,
#ifdef CONFIG_DMA_NUMA_CMA
int nid = dev_to_node(dev);
#endif
+ /*
+ * CoCo shared allocations require CMA alignment large enough for the
+ * architecture's shared-buffer granule.
+ */
+ if (attrs & __DMA_ATTR_ALLOC_CC_SHARED) {
+ if (get_order(mem_cc_shared_granule_size()) > CONFIG_CMA_ALIGNMENT)
+ return NULL;
+ }
/* CMA can be used only in the context which permits sleeping */
if (!gfpflags_allow_blocking(gfp))
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index fe02e8a3c0bb..82d3ce39db0a 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -285,6 +285,9 @@ void *dma_direct_alloc(struct device *dev, size_t size,
return NULL;
}
+ if (mark_mem_decrypt)
+ size = mem_cc_align_to_shared_granule(size);
+
/* we always manually zero the memory once we are done */
page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO,
allow_highmem, attrs);
@@ -407,6 +410,9 @@ void dma_direct_free(struct device *dev, size_t size,
/* Swiotlb doesn't need a page attribute update on free */
mark_mem_encrypted = false;
+ if (mark_mem_encrypted && force_dma_unencrypted(dev))
+ size = mem_cc_align_to_shared_granule(size);
+
if (is_vmalloc_addr(cpu_addr)) {
vunmap(cpu_addr);
} else {
@@ -453,6 +459,9 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
goto setup_page;
}
+ if (attrs & __DMA_ATTR_ALLOC_CC_SHARED)
+ size = mem_cc_align_to_shared_granule(size);
+
page = __dma_direct_alloc_pages(dev, size, gfp, false, attrs);
if (!page)
return NULL;
@@ -493,8 +502,11 @@ void dma_direct_free_pages(struct device *dev, size_t size,
if (swiotlb_pool)
mark_mem_encrypted = false;
- if (mark_mem_encrypted && dma_set_encrypted(dev, vaddr, size))
- return;
+ if (mark_mem_encrypted) {
+ size = mem_cc_align_to_shared_granule(size);
+ if (dma_set_encrypted(dev, vaddr, size))
+ return;
+ }
if (swiotlb_pool)
swiotlb_free_from_pool(dev, phys, swiotlb_pool);
diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
index 00f422a1e896..fc4a834aaa14 100644
--- a/kernel/dma/pool.c
+++ b/kernel/dma/pool.c
@@ -91,7 +91,9 @@ static int atomic_pool_expand(struct dma_gen_pool *dma_pool, size_t pool_size,
void *addr;
int ret = -ENOMEM;
pgprot_t prot __maybe_unused;
+ unsigned int min_encrypt_order = get_order(mem_cc_shared_granule_size());
+ pool_size = mem_cc_align_to_shared_granule(pool_size);
/* Cannot allocate larger than MAX_PAGE_ORDER */
order = min(get_order(pool_size), MAX_PAGE_ORDER);
@@ -102,7 +104,7 @@ static int atomic_pool_expand(struct dma_gen_pool *dma_pool, size_t pool_size,
order, false);
if (!page)
page = alloc_pages(gfp | __GFP_NOWARN, order);
- } while (!page && order-- > 0);
+ } while (!page && order-- > min_encrypt_order);
if (!page)
goto out;
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v6 5/9] swiotlb: Align shared IO TLB pools to the shared granule size
2026-09-04 10:34 [PATCH v6 0/9] coco: guest: Enforce host page-size alignment for shared buffers Aneesh Kumar K.V (Arm)
` (3 preceding siblings ...)
2026-09-04 10:34 ` [PATCH v6 4/9] dma-direct: Align CoCo shared DMA allocations to the shared granule size Aneesh Kumar K.V (Arm)
@ 2026-09-04 10:34 ` Aneesh Kumar K.V (Arm)
2026-09-04 10:34 ` [PATCH v6 6/9] swiotlb: Reject misaligned restricted DMA pools for CoCo guests Aneesh Kumar K.V (Arm)
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 10:34 UTC (permalink / raw)
To: linux-coco, kvmarm, linux-arm-kernel, linux-kernel, iommu
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Jason Gunthorpe,
Marc Zyngier, Marek Szyprowski, Robin Murphy, Steven Price,
Suzuki K Poulose, Thomas Gleixner, Will Deacon
swiotlb pools used by confidential-computing guests are shared with the
host and therefore must be converted at the host shared-granule size. A
PAGE_SIZE-sized or PAGE_SIZE-aligned pool is not sufficient when the host
tracks shared state at a larger granularity.
Round swiotlb pool sizes to mem_cc_shared_granule_size(), allocate the
pools at that alignment, and use the same aligned size when decrypting,
encrypting and freeing pool memory. Apply the same rule to dynamically
allocated swiotlb pools.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
kernel/dma/swiotlb.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index ded7016a46a7..f8936b03d942 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -369,7 +369,8 @@ void __init swiotlb_update_mem_attributes(void)
if (!mem->nslabs || mem->late_alloc)
return;
- bytes = PAGE_ALIGN(mem->nslabs << IO_TLB_SHIFT);
+
+ bytes = mem_cc_align_to_shared_granule(mem->nslabs << IO_TLB_SHIFT);
if (io_tlb_default_mem.cc_shared) {
int ret;
@@ -436,8 +437,8 @@ static void __init *swiotlb_memblock_alloc(unsigned long nslabs,
unsigned int flags,
int (*remap)(void *tlb, unsigned long nslabs))
{
- size_t bytes = PAGE_ALIGN(nslabs << IO_TLB_SHIFT);
void *tlb;
+ size_t bytes = mem_cc_align_to_shared_granule(nslabs << IO_TLB_SHIFT);
/*
* By default allocate the bounce buffer memory from low memory, but
@@ -445,9 +446,9 @@ static void __init *swiotlb_memblock_alloc(unsigned long nslabs,
* memory encryption.
*/
if (flags & SWIOTLB_ANY)
- tlb = memblock_alloc(bytes, PAGE_SIZE);
+ tlb = memblock_alloc(bytes, mem_cc_shared_granule_size());
else
- tlb = memblock_alloc_low(bytes, PAGE_SIZE);
+ tlb = memblock_alloc_low(bytes, mem_cc_shared_granule_size());
if (!tlb) {
pr_warn("%s: Failed to allocate %zu bytes tlb structure\n",
@@ -456,7 +457,7 @@ static void __init *swiotlb_memblock_alloc(unsigned long nslabs,
}
if (remap && remap(tlb, nslabs) < 0) {
- memblock_free(tlb, PAGE_ALIGN(bytes));
+ memblock_free(tlb, bytes);
pr_warn("%s: Failed to remap %zu bytes\n", __func__, bytes);
return NULL;
}
@@ -578,7 +579,7 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
swiotlb_adjust_nareas(num_possible_cpus());
retry:
- order = get_order(nslabs << IO_TLB_SHIFT);
+ order = get_order(mem_cc_align_to_shared_granule(nslabs << IO_TLB_SHIFT));
nslabs = SLABS_PER_PAGE << order;
while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) {
@@ -587,6 +588,8 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
if (vstart)
break;
order--;
+ if (order < get_order(mem_cc_shared_granule_size()))
+ break;
nslabs = SLABS_PER_PAGE << order;
retried = true;
}
@@ -667,7 +670,7 @@ void __init swiotlb_exit(void)
pr_info("tearing down default memory pool\n");
tbl_vaddr = (unsigned long)phys_to_virt(mem->start);
- tbl_size = PAGE_ALIGN(mem->end - mem->start);
+ tbl_size = mem_cc_align_to_shared_granule(mem->end - mem->start);
slots_size = PAGE_ALIGN(array_size(sizeof(*mem->slots), mem->nslabs));
if (io_tlb_default_mem.cc_shared) {
@@ -711,12 +714,14 @@ void __init swiotlb_exit(void)
static struct page *alloc_dma_pages(gfp_t gfp, size_t bytes,
u64 phys_limit, unsigned long attrs)
{
- unsigned int order = get_order(bytes);
bool cc_shared = attrs & __DMA_ATTR_ALLOC_CC_SHARED;
+ unsigned int order;
struct page *page;
phys_addr_t paddr;
void *vaddr;
+ bytes = mem_cc_align_to_shared_granule(bytes);
+ order = get_order(bytes);
page = alloc_pages(gfp, order);
if (!page)
return NULL;
@@ -807,6 +812,7 @@ static void swiotlb_free_tlb(void *vaddr, size_t bytes, bool cc_shared)
dma_free_from_pool(NULL, vaddr, bytes))
return;
+ bytes = mem_cc_align_to_shared_granule(bytes);
/* Intentional leak if pages cannot be encrypted again. */
if (!cc_shared ||
!set_memory_encrypted((unsigned long)vaddr, PFN_UP(bytes)))
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v6 6/9] swiotlb: Reject misaligned restricted DMA pools for CoCo guests
2026-09-04 10:34 [PATCH v6 0/9] coco: guest: Enforce host page-size alignment for shared buffers Aneesh Kumar K.V (Arm)
` (4 preceding siblings ...)
2026-09-04 10:34 ` [PATCH v6 5/9] swiotlb: Align shared IO TLB pools " Aneesh Kumar K.V (Arm)
@ 2026-09-04 10:34 ` Aneesh Kumar K.V (Arm)
2026-09-04 10:34 ` [PATCH v6 7/9] dma-buf: system_heap: Enforce shared-granule alignment for cc-shared buffers Aneesh Kumar K.V (Arm)
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 10:34 UTC (permalink / raw)
To: linux-coco, kvmarm, linux-arm-kernel, linux-kernel, iommu
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Jason Gunthorpe,
Marc Zyngier, Marek Szyprowski, Robin Murphy, Steven Price,
Suzuki K Poulose, Thomas Gleixner, Will Deacon
Restricted DMA pools are described by firmware reserved-memory nodes and
are not resized or realigned by the kernel. For confidential-computing
guests, such pools can only be shared safely when both the base address and
size are aligned to the shared-granule size.
Reject restricted DMA pools that are not aligned to
mem_cc_shared_granule_size() when guest memory encryption is active.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
kernel/dma/swiotlb.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index f8936b03d942..d1bd06be628d 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -2037,6 +2037,20 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
* if platform supports memory encryption,
* restricted mem pool is shared by default
*/
+ if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) {
+ size_t cc_shared_granule_size = mem_cc_shared_granule_size();
+
+ if (!IS_ALIGNED(rmem->base, cc_shared_granule_size) ||
+ !IS_ALIGNED(rmem->size, cc_shared_granule_size)) {
+ dev_err(dev, "Restricted DMA pool must be aligned to %#zx bytes for memory encryption\n",
+ cc_shared_granule_size);
+ kfree(pool->areas);
+ kfree(pool->slots);
+ kfree(mem);
+ return -EINVAL;
+ }
+ }
+
if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
int ret;
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v6 7/9] dma-buf: system_heap: Enforce shared-granule alignment for cc-shared buffers
2026-09-04 10:34 [PATCH v6 0/9] coco: guest: Enforce host page-size alignment for shared buffers Aneesh Kumar K.V (Arm)
` (5 preceding siblings ...)
2026-09-04 10:34 ` [PATCH v6 6/9] swiotlb: Reject misaligned restricted DMA pools for CoCo guests Aneesh Kumar K.V (Arm)
@ 2026-09-04 10:34 ` Aneesh Kumar K.V (Arm)
2026-09-04 10:34 ` [PATCH v6 8/9] arm64: realm: Add RHI helper to query IPA state change alignment Aneesh Kumar K.V (Arm)
2026-09-04 10:34 ` [PATCH v6 9/9] arm64: realm: Expose the CCA shared granule size through mem_encrypt ops Aneesh Kumar K.V (Arm)
8 siblings, 0 replies; 10+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 10:34 UTC (permalink / raw)
To: linux-coco, kvmarm, linux-arm-kernel, linux-kernel, iommu
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Jason Gunthorpe,
Marc Zyngier, Marek Szyprowski, Robin Murphy, Steven Price,
Suzuki K Poulose, Thomas Gleixner, Will Deacon
The system heap can allocate buffers that are decrypted and shared with the
host. For confidential-computing guests, those shared buffers must cover
whole shared-buffer granule; otherwise a userspace mmap of the dma-buf may
expose only part of a host-managed granule and allow unintended access to
adjacent private memory.
Require cc-shared system-heap allocations to have a size aligned to
mem_cc_shared_granule_size(), and allocate pages at least as large as the
required granule. Keep the allocation bounded by the existing heap orders,
but fall back to an exact minimum-order allocation when the required
granule is not one of the preferred heap orders.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
drivers/dma-buf/heaps/system_heap.c | 50 +++++++++++++++++++++++------
1 file changed, 41 insertions(+), 9 deletions(-)
diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index c8959eadc71d..9cbfcebe2088 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -55,7 +55,6 @@ struct dma_heap_attachment {
#define HIGH_ORDER_GFP (((GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN \
| __GFP_NORETRY) & ~__GFP_RECLAIM) \
| __GFP_COMP)
-static gfp_t order_flags[] = {HIGH_ORDER_GFP, HIGH_ORDER_GFP, LOW_ORDER_GFP};
/*
* The selection of the orders used for allocation (1MB, 64K, 4K) is designed
* to match with the sizes often found in IOMMUs. Using order 4 pages instead
@@ -375,26 +374,44 @@ static const struct dma_buf_ops system_heap_buf_ops = {
.release = system_heap_dma_buf_release,
};
+static struct page *system_heap_alloc_order(unsigned int order)
+{
+ gfp_t flags = order ? HIGH_ORDER_GFP : LOW_ORDER_GFP;
+
+ if (mem_accounting)
+ flags |= __GFP_ACCOUNT;
+
+ return alloc_pages(flags, order);
+}
+
static struct page *alloc_largest_available(unsigned long size,
- unsigned int max_order)
+ unsigned int max_order,
+ unsigned int min_order)
{
struct page *page;
int i;
- gfp_t flags;
for (i = 0; i < NUM_ORDERS; i++) {
if (size < (PAGE_SIZE << orders[i]))
continue;
- if (max_order < orders[i])
+
+ if (max_order < orders[i] || orders[i] < min_order)
continue;
- flags = order_flags[i];
- if (mem_accounting)
- flags |= __GFP_ACCOUNT;
- page = alloc_pages(flags, orders[i]);
+
+ page = system_heap_alloc_order(orders[i]);
if (!page)
continue;
return page;
}
+ /*
+ * The required minimum order might not be one of the preferred heap
+ * orders. Allocate exactly min_order when it does not exceed the
+ * remaining size.
+ */
+ if (min_order && min_order <= max_order &&
+ size >= (PAGE_SIZE << min_order))
+ return system_heap_alloc_order(min_order);
+
return NULL;
}
@@ -409,6 +426,8 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
unsigned int max_order = orders[0];
struct system_heap_priv *priv = dma_heap_get_drvdata(heap);
bool cc_shared = priv->cc_shared;
+ unsigned int min_order = 0;
+ size_t cc_granule_size;
struct dma_buf *dmabuf;
struct sg_table *table;
struct scatterlist *sg;
@@ -425,6 +444,18 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
buffer->heap = heap;
buffer->len = len;
buffer->cc_shared = cc_shared;
+ if (cc_shared_buffer(buffer)) {
+ cc_granule_size = mem_cc_shared_granule_size();
+ if (!IS_ALIGNED(len, cc_granule_size)) {
+ ret = -EINVAL;
+ goto free_buffer;
+ }
+ min_order = get_order(cc_granule_size);
+ if (min_order > max_order) {
+ ret = -EINVAL;
+ goto free_buffer;
+ }
+ }
INIT_LIST_HEAD(&pages);
i = 0;
@@ -438,7 +469,8 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
goto free_buffer;
}
- page = alloc_largest_available(size_remaining, max_order);
+ page = alloc_largest_available(size_remaining, max_order,
+ min_order);
if (!page)
goto free_buffer;
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v6 8/9] arm64: realm: Add RHI helper to query IPA state change alignment
2026-09-04 10:34 [PATCH v6 0/9] coco: guest: Enforce host page-size alignment for shared buffers Aneesh Kumar K.V (Arm)
` (6 preceding siblings ...)
2026-09-04 10:34 ` [PATCH v6 7/9] dma-buf: system_heap: Enforce shared-granule alignment for cc-shared buffers Aneesh Kumar K.V (Arm)
@ 2026-09-04 10:34 ` Aneesh Kumar K.V (Arm)
2026-09-04 10:34 ` [PATCH v6 9/9] arm64: realm: Expose the CCA shared granule size through mem_encrypt ops Aneesh Kumar K.V (Arm)
8 siblings, 0 replies; 10+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 10:34 UTC (permalink / raw)
To: linux-coco, kvmarm, linux-arm-kernel, linux-kernel, iommu
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Jason Gunthorpe,
Marc Zyngier, Marek Szyprowski, Robin Murphy, Steven Price,
Suzuki K Poulose, Thomas Gleixner, Will Deacon
Arm CCA guests need to know the granularity at which the host expects IPA
state changes to be performed. This can be larger than the guest page size
and is needed when deciding the alignment for memory shared with the host.
Add the Realm Host Interface host configuration definitions and an
get_ipa_state_change_alignment() helper. The helper uses RSI_HOST_CALL to
query the supported HostConf version and features, reads the IPA change
alignment when available, and falls back to PAGE_SIZE if the interface is
unavailable or returns an invalid value.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
drivers/firmware/arm_rmm/rsi.c | 46 ++++++++++++++++++++++++++++++++++
include/linux/arm-rsi-cmds.h | 10 ++++++++
include/linux/arm-smccc-rhi.h | 25 ++++++++++++++++++
include/linux/arm-smccc-rsi.h | 7 ++++++
4 files changed, 88 insertions(+)
create mode 100644 include/linux/arm-smccc-rhi.h
diff --git a/drivers/firmware/arm_rmm/rsi.c b/drivers/firmware/arm_rmm/rsi.c
index 52f40256bd78..2cd53f82432f 100644
--- a/drivers/firmware/arm_rmm/rsi.c
+++ b/drivers/firmware/arm_rmm/rsi.c
@@ -9,6 +9,7 @@
#include <linux/swiotlb.h>
#include <linux/platform_device.h>
#include <linux/arm-rsi-cmds.h>
+#include <linux/arm-smccc-rhi.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
@@ -164,6 +165,51 @@ static int realm_register_memory_enc_ops(void)
return arm64_mem_crypt_ops_register(&realm_crypt_ops);
}
+/* we need an aligned struct for rsi_host_call. slab is not yet ready */
+static struct rsi_host_call hostconf_call __initdata;
+static unsigned long __maybe_unused __init get_ipa_state_change_alignment(void)
+{
+ long ret;
+ unsigned long shared_granule_size;
+
+ hostconf_call.imm = 0;
+ hostconf_call.gprs[0] = RHI_HOSTCONF_VERSION;
+ ret = rsi_host_call(lm_alias(&hostconf_call));
+ if (ret != RSI_SUCCESS)
+ goto err_out;
+
+ if (hostconf_call.gprs[0] != RHI_HOSTCONF_VER_1_0)
+ goto err_out;
+
+ hostconf_call.imm = 0;
+ hostconf_call.gprs[0] = RHI_HOSTCONF_FEATURES;
+ ret = rsi_host_call(lm_alias(&hostconf_call));
+ if (ret != RSI_SUCCESS)
+ goto err_out;
+
+ if (!(hostconf_call.gprs[0] & __RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT))
+ goto err_out;
+
+ hostconf_call.imm = 0;
+ hostconf_call.gprs[0] = RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT;
+ ret = rsi_host_call(lm_alias(&hostconf_call));
+ if (ret != RSI_SUCCESS)
+ goto err_out;
+
+ shared_granule_size = hostconf_call.gprs[0];
+ if (shared_granule_size & (SZ_4K - 1) ||
+ !is_power_of_2(shared_granule_size))
+ goto err_out;
+
+ return max(PAGE_SIZE, shared_granule_size);
+err_out:
+ /*
+ * For failure condition assume host is built with 4K page size
+ * and hence IPA state change alignment can be guest PAGE_SIZE.
+ */
+ return PAGE_SIZE;
+}
+
void __init arm64_rsi_init(void)
{
if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC)
diff --git a/include/linux/arm-rsi-cmds.h b/include/linux/arm-rsi-cmds.h
index 3f7a6a833993..996f1621b996 100644
--- a/include/linux/arm-rsi-cmds.h
+++ b/include/linux/arm-rsi-cmds.h
@@ -236,4 +236,14 @@ static inline unsigned long rsi_attestation_token_continue(phys_addr_t granule,
return res.a0;
}
+static inline unsigned long rsi_host_call(struct rsi_host_call *rhi_call)
+{
+ phys_addr_t addr = virt_to_phys(rhi_call);
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_invoke(SMC_RSI_HOST_CALL, addr, &res);
+
+ return res.a0;
+}
+
#endif /* __LINUX_ARM_RSI_CMDS_H_ */
diff --git a/include/linux/arm-smccc-rhi.h b/include/linux/arm-smccc-rhi.h
new file mode 100644
index 000000000000..91a29996d72d
--- /dev/null
+++ b/include/linux/arm-smccc-rhi.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2026 ARM Ltd.
+ */
+
+#ifndef __LINUX_ARM_SMCCC_RHI_H_
+#define __LINUX_ARM_SMCCC_RHI_H_
+
+#include <linux/arm-smccc.h>
+
+#define SMC_RHI_CALL(func) \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_STANDARD_HYP,\
+ (func))
+
+#define RHI_HOSTCONF_VER_1_0 0x10000
+#define RHI_HOSTCONF_VERSION SMC_RHI_CALL(0x004E)
+
+#define __RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT BIT(0)
+#define RHI_HOSTCONF_FEATURES SMC_RHI_CALL(0x004F)
+
+#define RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT SMC_RHI_CALL(0x0050)
+
+#endif /* __LINUX_ARM_SMCCC_RHI_H_ */
diff --git a/include/linux/arm-smccc-rsi.h b/include/linux/arm-smccc-rsi.h
index fddb77986f70..3532a3f08f4e 100644
--- a/include/linux/arm-smccc-rsi.h
+++ b/include/linux/arm-smccc-rsi.h
@@ -182,6 +182,13 @@ struct realm_config {
*/
#define SMC_RSI_IPA_STATE_GET SMC_RSI_FID(0x198)
+struct rsi_host_call {
+ union {
+ u16 imm;
+ u64 padding0;
+ };
+ u64 gprs[31];
+} __aligned(0x100);
/*
* Make a Host call.
*
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v6 9/9] arm64: realm: Expose the CCA shared granule size through mem_encrypt ops
2026-09-04 10:34 [PATCH v6 0/9] coco: guest: Enforce host page-size alignment for shared buffers Aneesh Kumar K.V (Arm)
` (7 preceding siblings ...)
2026-09-04 10:34 ` [PATCH v6 8/9] arm64: realm: Add RHI helper to query IPA state change alignment Aneesh Kumar K.V (Arm)
@ 2026-09-04 10:34 ` Aneesh Kumar K.V (Arm)
8 siblings, 0 replies; 10+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 10:34 UTC (permalink / raw)
To: linux-coco, kvmarm, linux-arm-kernel, linux-kernel, iommu
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Jason Gunthorpe,
Marc Zyngier, Marek Szyprowski, Robin Murphy, Steven Price,
Suzuki K Poulose, Thomas Gleixner, Will Deacon
CCA guests must align shared/private memory transitions to the size
reported by the host for IPA state changes. This size can be larger than
PAGE_SIZE, so allowing a guest to convert only a PAGE_SIZE-sized subrange
can leave the remaining part of that host-sized range in the wrong state.
Cache the RHI-reported IPA sate change alignment during Realm
initialization and expose it through a new arm64 mem_encrypt callback. Use
PAGE_SIZE as the default shared granule size when no backend callback is
registered.
Validate both the address and byte size passed to set_memory_encrypted()
and set_memory_decrypted() against mem_cc_shared_granule_size() before
calling into the backend. This prevents callers from converting only part
of a host-managed page.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
arch/arm64/include/asm/mem_encrypt.h | 4 ++++
arch/arm64/mm/mem_encrypt.c | 32 ++++++++++++++++++++++++----
drivers/firmware/arm_rmm/rsi.c | 13 ++++++++++-
3 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/mem_encrypt.h b/arch/arm64/include/asm/mem_encrypt.h
index ef8b8463e52b..890faeed0eb3 100644
--- a/arch/arm64/include/asm/mem_encrypt.h
+++ b/arch/arm64/include/asm/mem_encrypt.h
@@ -10,6 +10,7 @@ struct device;
struct arm64_mem_crypt_ops {
int (*encrypt)(unsigned long addr, int numpages);
int (*decrypt)(unsigned long addr, int numpages);
+ size_t (*cc_shared_granule_size)(void);
};
int arm64_mem_crypt_ops_register(const struct arm64_mem_crypt_ops *ops);
@@ -18,6 +19,9 @@ int set_memory_encrypted(unsigned long addr, int numpages);
int set_memory_decrypted(unsigned long addr, int numpages);
int __set_memory_enc_dec(unsigned long addr, int numpages, bool encrypt);
+#define mem_cc_shared_granule_size mem_cc_shared_granule_size
+size_t mem_cc_shared_granule_size(void);
+
static inline bool force_dma_unencrypted(struct device *dev)
{
return is_realm_world() || is_protected_kvm_guest();
diff --git a/arch/arm64/mm/mem_encrypt.c b/arch/arm64/mm/mem_encrypt.c
index ee3c0ab04384..69783c6a3c08 100644
--- a/arch/arm64/mm/mem_encrypt.c
+++ b/arch/arm64/mm/mem_encrypt.c
@@ -17,8 +17,7 @@
#include <linux/compiler.h>
#include <linux/err.h>
#include <linux/mm.h>
-
-#include <asm/mem_encrypt.h>
+#include <linux/mem_encrypt.h>
static const struct arm64_mem_crypt_ops *crypt_ops;
@@ -33,18 +32,43 @@ int arm64_mem_crypt_ops_register(const struct arm64_mem_crypt_ops *ops)
int set_memory_encrypted(unsigned long addr, int numpages)
{
- if (likely(!crypt_ops) || WARN_ON(!PAGE_ALIGNED(addr)))
+ unsigned long size = (unsigned long)numpages << PAGE_SHIFT;
+
+ if (likely(!crypt_ops))
return 0;
+ if (WARN_ON(!IS_ALIGNED(addr, mem_cc_shared_granule_size())))
+ return -EINVAL;
+
+ if (WARN_ON(!IS_ALIGNED(size, mem_cc_shared_granule_size())))
+ return -EINVAL;
+
return crypt_ops->encrypt(addr, numpages);
}
EXPORT_SYMBOL_GPL(set_memory_encrypted);
int set_memory_decrypted(unsigned long addr, int numpages)
{
- if (likely(!crypt_ops) || WARN_ON(!PAGE_ALIGNED(addr)))
+ unsigned long size = (unsigned long)numpages << PAGE_SHIFT;
+
+ if (likely(!crypt_ops))
return 0;
+ if (WARN_ON(!IS_ALIGNED(addr, mem_cc_shared_granule_size())))
+ return -EINVAL;
+
+ if (WARN_ON(!IS_ALIGNED(size, mem_cc_shared_granule_size())))
+ return -EINVAL;
+
return crypt_ops->decrypt(addr, numpages);
}
EXPORT_SYMBOL_GPL(set_memory_decrypted);
+
+size_t mem_cc_shared_granule_size(void)
+{
+ if (likely(!crypt_ops) || !crypt_ops->cc_shared_granule_size)
+ return PAGE_SIZE;
+
+ return crypt_ops->cc_shared_granule_size();
+}
+EXPORT_SYMBOL_GPL(mem_cc_shared_granule_size);
diff --git a/drivers/firmware/arm_rmm/rsi.c b/drivers/firmware/arm_rmm/rsi.c
index 2cd53f82432f..eeb797c6c2c7 100644
--- a/drivers/firmware/arm_rmm/rsi.c
+++ b/drivers/firmware/arm_rmm/rsi.c
@@ -19,6 +19,7 @@
static struct realm_config config;
static struct kobject *cca_kobj;
+static unsigned long ipa_state_change_granule_size;
unsigned long prot_ns_shared;
EXPORT_SYMBOL(prot_ns_shared);
@@ -155,9 +156,17 @@ static int realm_set_memory_decrypted(unsigned long addr, int numpages)
return ret;
}
+static size_t realm_cc_shared_granule_size(void)
+{
+ if (is_realm_world())
+ return ipa_state_change_granule_size;
+ return PAGE_SIZE;
+}
+
static const struct arm64_mem_crypt_ops realm_crypt_ops = {
.encrypt = realm_set_memory_encrypted,
.decrypt = realm_set_memory_decrypted,
+ .cc_shared_granule_size = realm_cc_shared_granule_size,
};
static int realm_register_memory_enc_ops(void)
@@ -167,7 +176,7 @@ static int realm_register_memory_enc_ops(void)
/* we need an aligned struct for rsi_host_call. slab is not yet ready */
static struct rsi_host_call hostconf_call __initdata;
-static unsigned long __maybe_unused __init get_ipa_state_change_alignment(void)
+static unsigned long __init get_ipa_state_change_alignment(void)
{
long ret;
unsigned long shared_granule_size;
@@ -218,6 +227,8 @@ void __init arm64_rsi_init(void)
return;
if (WARN_ON(rsi_get_realm_config(lm_alias(&config))))
return;
+
+ ipa_state_change_granule_size = get_ipa_state_change_alignment();
prot_ns_shared = __phys_to_pte_val(BIT(config.ipa_bits - 1));
if (arm64_ioremap_prot_hook_register(realm_ioremap_hook))
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread