* [PATCH 0/3] arm64/coco: Convert pKVM to a CC platform
@ 2026-06-03 11:05 Mostafa Saleh
2026-06-03 11:05 ` [PATCH 1/3] arm64/mm: Simplify SWIOTLB setup in arch_mm_preinit() Mostafa Saleh
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Mostafa Saleh @ 2026-06-03 11:05 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel
Cc: akpm, catalin.marinas, will, rppt, maz, aneesh.kumar,
Mostafa Saleh
The goal of series is to convert pKVM as a CC platform similar to
ARM CCA, that makes CC guests consistently discovered which avoid
breaking it by the ongoing DMA rework [1]
The first patch is a minor clean up I noticed while reading the code.
And the second patch is a bug fix found by Sashiko.
The third patch is the main one.
[1]https://lore.kernel.org/all/20260522042815.370873-1-aneesh.kumar@kernel.org/
Mostafa Saleh (3):
arm64/mm: Simplify SWIOTLB setup in arch_mm_preinit()
drivers/virt: pkvm: Fix end calculation in mmio_guard_ioremap_hook()
arm64/coco: Add pKVM as a CC platform
arch/arm64/include/asm/hypervisor.h | 13 ++++++++++
arch/arm64/include/asm/mem_encrypt.h | 3 ++-
arch/arm64/kernel/rsi.c | 12 ---------
arch/arm64/mm/init.c | 26 +++++++++++++------
drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c | 5 +++-
5 files changed, 37 insertions(+), 22 deletions(-)
--
2.54.0.1032.g2f8565e1d1-goog
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/3] arm64/mm: Simplify SWIOTLB setup in arch_mm_preinit()
2026-06-03 11:05 [PATCH 0/3] arm64/coco: Convert pKVM to a CC platform Mostafa Saleh
@ 2026-06-03 11:05 ` Mostafa Saleh
2026-06-03 12:27 ` Mike Rapoport
2026-06-03 11:05 ` [PATCH 2/3] drivers/virt: pkvm: Fix end calculation in mmio_guard_ioremap_hook() Mostafa Saleh
2026-06-03 11:05 ` [PATCH 3/3] arm64/coco: Add pKVM as a CC platform Mostafa Saleh
2 siblings, 1 reply; 6+ messages in thread
From: Mostafa Saleh @ 2026-06-03 11:05 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel
Cc: akpm, catalin.marinas, will, rppt, maz, aneesh.kumar,
Mostafa Saleh
At the moment, arch_mm_preinit() checks if the system has limited
addressing or is running under CCA to enable SWIOTLB, only after to
be forced to true anyway if it was false due to
CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC being unconditionally true for
arm64.
Simplify this logic, by making it clear that SWIOTLB is always used
but its size depends on the address layout of the system.
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
arch/arm64/mm/init.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 97987f850a33..fcc9c05a8fe6 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -336,25 +336,22 @@ void __init arch_setup_zero_pages(void)
void __init arch_mm_preinit(void)
{
unsigned int flags = SWIOTLB_VERBOSE;
- bool swiotlb = max_pfn > PFN_DOWN(arm64_dma_phys_limit);
+ bool limited_addressing = max_pfn > PFN_DOWN(arm64_dma_phys_limit);
if (is_realm_world()) {
- swiotlb = true;
flags |= SWIOTLB_FORCE;
- }
-
- if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) && !swiotlb) {
+ } else if (!limited_addressing) {
/*
* If no bouncing needed for ZONE_DMA, reduce the swiotlb
* buffer for kmalloc() bouncing to 1MB per 1GB of RAM.
*/
unsigned long size =
DIV_ROUND_UP(memblock_phys_mem_size(), 1024);
+
swiotlb_adjust_size(min(swiotlb_size_or_default(), size));
- swiotlb = true;
}
- swiotlb_init(swiotlb, flags);
+ swiotlb_init(true, flags);
/*
* Check boundaries twice: Some fundamental inconsistencies can be
--
2.54.0.1032.g2f8565e1d1-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] drivers/virt: pkvm: Fix end calculation in mmio_guard_ioremap_hook()
2026-06-03 11:05 [PATCH 0/3] arm64/coco: Convert pKVM to a CC platform Mostafa Saleh
2026-06-03 11:05 ` [PATCH 1/3] arm64/mm: Simplify SWIOTLB setup in arch_mm_preinit() Mostafa Saleh
@ 2026-06-03 11:05 ` Mostafa Saleh
2026-06-03 11:05 ` [PATCH 3/3] arm64/coco: Add pKVM as a CC platform Mostafa Saleh
2 siblings, 0 replies; 6+ messages in thread
From: Mostafa Saleh @ 2026-06-03 11:05 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel
Cc: akpm, catalin.marinas, will, rppt, maz, aneesh.kumar,
Mostafa Saleh
Sashiko (locally) reports a logical issues in mmio_guard_ioremap_hook()
mmio_guard_ioremap_hook() attempts to handle unaligned addresses and
sizes. However, aligning the start address before adding the size, might
shift the end to the page before.
Fixes: 0f1269495800 ("drivers/virt: pkvm: Intercept ioremap using pKVM MMIO_GUARD hypercall")
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c b/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
index 4230b817a80b..d66291def0f4 100644
--- a/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
+++ b/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
@@ -82,8 +82,8 @@ static int mmio_guard_ioremap_hook(phys_addr_t phys, size_t size,
if (protval != PROT_DEVICE_nGnRE && protval != PROT_DEVICE_nGnRnE)
return 0;
+ end = PAGE_ALIGN(phys + size);
phys = PAGE_ALIGN_DOWN(phys);
- end = phys + PAGE_ALIGN(size);
while (phys < end) {
const int func_id = ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID;
--
2.54.0.1032.g2f8565e1d1-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] arm64/coco: Add pKVM as a CC platform
2026-06-03 11:05 [PATCH 0/3] arm64/coco: Convert pKVM to a CC platform Mostafa Saleh
2026-06-03 11:05 ` [PATCH 1/3] arm64/mm: Simplify SWIOTLB setup in arch_mm_preinit() Mostafa Saleh
2026-06-03 11:05 ` [PATCH 2/3] drivers/virt: pkvm: Fix end calculation in mmio_guard_ioremap_hook() Mostafa Saleh
@ 2026-06-03 11:05 ` Mostafa Saleh
2 siblings, 0 replies; 6+ messages in thread
From: Mostafa Saleh @ 2026-06-03 11:05 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel
Cc: akpm, catalin.marinas, will, rppt, maz, aneesh.kumar,
Mostafa Saleh
pKVM does support memory encryption, expose that to the rest of
the kernel through cc_platform_has()
At the moment, all devices inside the guest are emulated which
requires its memory to be shared back to the host (decrypted), so
set force_dma_unencrypted() to always return true.
Although, typically pKVM guests rely on restricted-dma-pools to
bounce traffic, with this change, it is possible to solely rely on
the default SWIOTLB for that (assuming the appropriate size is set
from the command line)
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
This change is critical for the ongoing refactoring of the DMA-API[1]
that will break protected guests under pKVM with this patch. That is
due to this rework will make the state of the SWIOTLB and restricted
dma pools depends on the value returned by cc_platform_has()
[1] https://lore.kernel.org/all/20260522042815.370873-1-aneesh.kumar@kernel.org/
---
arch/arm64/include/asm/hypervisor.h | 13 +++++++++++++
arch/arm64/include/asm/mem_encrypt.h | 3 ++-
arch/arm64/kernel/rsi.c | 12 ------------
arch/arm64/mm/init.c | 15 ++++++++++++++-
drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c | 3 +++
5 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/include/asm/hypervisor.h b/arch/arm64/include/asm/hypervisor.h
index a12fd897c877..8889a0ba1ec5 100644
--- a/arch/arm64/include/asm/hypervisor.h
+++ b/arch/arm64/include/asm/hypervisor.h
@@ -3,6 +3,9 @@
#define _ASM_ARM64_HYPERVISOR_H
#include <asm/xen/hypervisor.h>
+#include <linux/jump_label.h>
+
+DECLARE_STATIC_KEY_FALSE(pkvm_guest);
void kvm_init_hyp_services(void);
bool kvm_arm_hyp_service_available(u32 func_id);
@@ -10,8 +13,18 @@ void kvm_arm_target_impl_cpu_init(void);
#ifdef CONFIG_ARM_PKVM_GUEST
void pkvm_init_hyp_services(void);
+
+static inline bool is_protected_kvm_guest(void)
+{
+ return static_branch_unlikely(&pkvm_guest);
+}
#else
static inline void pkvm_init_hyp_services(void) { };
+
+static inline bool is_protected_kvm_guest(void)
+{
+ return false;
+}
#endif
static inline void kvm_arch_init_hyp_services(void)
diff --git a/arch/arm64/include/asm/mem_encrypt.h b/arch/arm64/include/asm/mem_encrypt.h
index 314b2b52025f..636f45b4d8af 100644
--- a/arch/arm64/include/asm/mem_encrypt.h
+++ b/arch/arm64/include/asm/mem_encrypt.h
@@ -2,6 +2,7 @@
#ifndef __ASM_MEM_ENCRYPT_H
#define __ASM_MEM_ENCRYPT_H
+#include <asm/hypervisor.h>
#include <asm/rsi.h>
struct device;
@@ -20,7 +21,7 @@ int realm_register_memory_enc_ops(void);
static inline bool force_dma_unencrypted(struct device *dev)
{
- return is_realm_world();
+ return is_realm_world() || is_protected_kvm_guest();
}
/*
diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
index 92160f2e57ff..25ca75ce1a4d 100644
--- a/arch/arm64/kernel/rsi.c
+++ b/arch/arm64/kernel/rsi.c
@@ -7,7 +7,6 @@
#include <linux/memblock.h>
#include <linux/psci.h>
#include <linux/swiotlb.h>
-#include <linux/cc_platform.h>
#include <linux/platform_device.h>
#include <asm/io.h>
@@ -23,17 +22,6 @@ EXPORT_SYMBOL(prot_ns_shared);
DEFINE_STATIC_KEY_FALSE_RO(rsi_present);
EXPORT_SYMBOL(rsi_present);
-bool cc_platform_has(enum cc_attr attr)
-{
- switch (attr) {
- case CC_ATTR_MEM_ENCRYPT:
- return is_realm_world();
- default:
- return false;
- }
-}
-EXPORT_SYMBOL_GPL(cc_platform_has);
-
static bool rsi_version_matches(void)
{
unsigned long ver_lower, ver_higher;
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index fcc9c05a8fe6..edcc305ec883 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -11,6 +11,7 @@
#include <linux/errno.h>
#include <linux/swap.h>
#include <linux/init.h>
+#include <linux/cc_platform.h>
#include <linux/cache.h>
#include <linux/mman.h>
#include <linux/nodemask.h>
@@ -36,6 +37,7 @@
#include <asm/boot.h>
#include <asm/fixmap.h>
+#include <asm/hypervisor.h>
#include <asm/kasan.h>
#include <asm/kernel-pgtable.h>
#include <asm/kvm_host.h>
@@ -338,7 +340,7 @@ void __init arch_mm_preinit(void)
unsigned int flags = SWIOTLB_VERBOSE;
bool limited_addressing = max_pfn > PFN_DOWN(arm64_dma_phys_limit);
- if (is_realm_world()) {
+ if (is_realm_world() || is_protected_kvm_guest()) {
flags |= SWIOTLB_FORCE;
} else if (!limited_addressing) {
/*
@@ -413,6 +415,17 @@ void dump_mem_limit(void)
}
}
+bool cc_platform_has(enum cc_attr attr)
+{
+ switch (attr) {
+ case CC_ATTR_MEM_ENCRYPT:
+ return is_realm_world() || is_protected_kvm_guest();
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL_GPL(cc_platform_has);
+
#ifdef CONFIG_EXECMEM
static u64 module_direct_base __ro_after_init = 0;
static u64 module_plt_base __ro_after_init = 0;
diff --git a/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c b/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
index d66291def0f4..26fe9c3f22e3 100644
--- a/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
+++ b/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
@@ -17,6 +17,7 @@
#include <asm/hypervisor.h>
static size_t pkvm_granule;
+DEFINE_STATIC_KEY_FALSE_RO(pkvm_guest);
static int arm_smccc_do_one_page(u32 func_id, phys_addr_t phys)
{
@@ -120,4 +121,6 @@ void pkvm_init_hyp_services(void)
if (kvm_arm_hyp_service_available(ARM_SMCCC_KVM_FUNC_MMIO_GUARD))
arm64_ioremap_prot_hook_register(&mmio_guard_ioremap_hook);
+
+ static_branch_enable(&pkvm_guest);
}
--
2.54.0.1032.g2f8565e1d1-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] arm64/mm: Simplify SWIOTLB setup in arch_mm_preinit()
2026-06-03 11:05 ` [PATCH 1/3] arm64/mm: Simplify SWIOTLB setup in arch_mm_preinit() Mostafa Saleh
@ 2026-06-03 12:27 ` Mike Rapoport
2026-06-03 13:13 ` Mostafa Saleh
0 siblings, 1 reply; 6+ messages in thread
From: Mike Rapoport @ 2026-06-03 12:27 UTC (permalink / raw)
To: Mostafa Saleh
Cc: linux-arm-kernel, linux-kernel, akpm, catalin.marinas, will, maz,
aneesh.kumar
Hi,
On Wed, Jun 03, 2026 at 11:05:20AM +0000, Mostafa Saleh wrote:
> At the moment, arch_mm_preinit() checks if the system has limited
> addressing or is running under CCA to enable SWIOTLB, only after to
> be forced to true anyway if it was false due to
> CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC being unconditionally true for
> arm64.
>
> Simplify this logic, by making it clear that SWIOTLB is always used
> but its size depends on the address layout of the system.
>
> Signed-off-by: Mostafa Saleh <smostafa@google.com>
> ---
> arch/arm64/mm/init.c | 11 ++++-------
> 1 file changed, 4 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 97987f850a33..fcc9c05a8fe6 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -336,25 +336,22 @@ void __init arch_setup_zero_pages(void)
> void __init arch_mm_preinit(void)
> {
> unsigned int flags = SWIOTLB_VERBOSE;
> - bool swiotlb = max_pfn > PFN_DOWN(arm64_dma_phys_limit);
> + bool limited_addressing = max_pfn > PFN_DOWN(arm64_dma_phys_limit);
>
> if (is_realm_world()) {
> - swiotlb = true;
> flags |= SWIOTLB_FORCE;
> - }
> -
> - if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) && !swiotlb) {
> + } else if (!limited_addressing) {
Can realm_world() coexist with limited_addressing? Then the size adjustment
is still required.
I'd also make this more explicit:
if (max_pfn > PFN_DOWN(arm64_dma_phys_limit))
> /*
> * If no bouncing needed for ZONE_DMA, reduce the swiotlb
> * buffer for kmalloc() bouncing to 1MB per 1GB of RAM.
> */
> unsigned long size =
> DIV_ROUND_UP(memblock_phys_mem_size(), 1024);
> +
> swiotlb_adjust_size(min(swiotlb_size_or_default(), size));
> - swiotlb = true;
> }
>
> - swiotlb_init(swiotlb, flags);
> + swiotlb_init(true, flags);
>
> /*
> * Check boundaries twice: Some fundamental inconsistencies can be
> --
> 2.54.0.1032.g2f8565e1d1-goog
>
--
Sincerely yours,
Mike.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] arm64/mm: Simplify SWIOTLB setup in arch_mm_preinit()
2026-06-03 12:27 ` Mike Rapoport
@ 2026-06-03 13:13 ` Mostafa Saleh
0 siblings, 0 replies; 6+ messages in thread
From: Mostafa Saleh @ 2026-06-03 13:13 UTC (permalink / raw)
To: Mike Rapoport
Cc: linux-arm-kernel, linux-kernel, akpm, catalin.marinas, will, maz,
aneesh.kumar
Hi Mike,
On Wed, Jun 03, 2026 at 03:27:52PM +0300, Mike Rapoport wrote:
> Hi,
>
> On Wed, Jun 03, 2026 at 11:05:20AM +0000, Mostafa Saleh wrote:
> > At the moment, arch_mm_preinit() checks if the system has limited
> > addressing or is running under CCA to enable SWIOTLB, only after to
> > be forced to true anyway if it was false due to
> > CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC being unconditionally true for
> > arm64.
> >
> > Simplify this logic, by making it clear that SWIOTLB is always used
> > but its size depends on the address layout of the system.
> >
> > Signed-off-by: Mostafa Saleh <smostafa@google.com>
> > ---
> > arch/arm64/mm/init.c | 11 ++++-------
> > 1 file changed, 4 insertions(+), 7 deletions(-)
> >
> > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > index 97987f850a33..fcc9c05a8fe6 100644
> > --- a/arch/arm64/mm/init.c
> > +++ b/arch/arm64/mm/init.c
> > @@ -336,25 +336,22 @@ void __init arch_setup_zero_pages(void)
> > void __init arch_mm_preinit(void)
> > {
> > unsigned int flags = SWIOTLB_VERBOSE;
> > - bool swiotlb = max_pfn > PFN_DOWN(arm64_dma_phys_limit);
> > + bool limited_addressing = max_pfn > PFN_DOWN(arm64_dma_phys_limit);
> >
> > if (is_realm_world()) {
> > - swiotlb = true;
> > flags |= SWIOTLB_FORCE;
> > - }
> > -
> > - if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) && !swiotlb) {
> > + } else if (!limited_addressing) {
>
> Can realm_world() coexist with limited_addressing? Then the size adjustment
> is still required.
My guess would be no, my understanding is that CCA guests have niche
hardware.
However, the check for limited_addressing is negated, we adjust the
SWIOTLB to be smaller if no bouncing is needed.
So, if this is a realm world, address space layout is irrelevant as we
keep the original size which is larger.
Otherwise, this alters the current behaviour.
>
> I'd also make this more explicit:
>
> if (max_pfn > PFN_DOWN(arm64_dma_phys_limit))
Sure, I can drop the bool.
Thanks,
Mostafa
>
> > /*
> > * If no bouncing needed for ZONE_DMA, reduce the swiotlb
> > * buffer for kmalloc() bouncing to 1MB per 1GB of RAM.
> > */
> > unsigned long size =
> > DIV_ROUND_UP(memblock_phys_mem_size(), 1024);
> > +
> > swiotlb_adjust_size(min(swiotlb_size_or_default(), size));
> > - swiotlb = true;
> > }
> >
> > - swiotlb_init(swiotlb, flags);
> > + swiotlb_init(true, flags);
> >
> > /*
> > * Check boundaries twice: Some fundamental inconsistencies can be
> > --
> > 2.54.0.1032.g2f8565e1d1-goog
> >
>
> --
> Sincerely yours,
> Mike.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-06-03 13:14 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-03 11:05 [PATCH 0/3] arm64/coco: Convert pKVM to a CC platform Mostafa Saleh
2026-06-03 11:05 ` [PATCH 1/3] arm64/mm: Simplify SWIOTLB setup in arch_mm_preinit() Mostafa Saleh
2026-06-03 12:27 ` Mike Rapoport
2026-06-03 13:13 ` Mostafa Saleh
2026-06-03 11:05 ` [PATCH 2/3] drivers/virt: pkvm: Fix end calculation in mmio_guard_ioremap_hook() Mostafa Saleh
2026-06-03 11:05 ` [PATCH 3/3] arm64/coco: Add pKVM as a CC platform Mostafa Saleh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox