* [PATCH v2 kvmtool 0/4] Add support for running protected VMs on arm64
@ 2026-06-25 17:10 Will Deacon
2026-06-25 17:10 ` [PATCH v2 kvmtool 1/4] Sync kernel UAPI headers with v7.1 Will Deacon
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Will Deacon @ 2026-06-25 17:10 UTC (permalink / raw)
To: kvm
Cc: kvmarm, Will Deacon, Alexandru Elisei, Suzuki K Poulose,
Andre Przywara, Fuad Tabba, Oliver Upton, Marc Zyngier
Hi folks,
This is v2 of the patches I previously posted here:
https://lore.kernel.org/r/20260619115415.5475-1-will@kernel.org
Changes since v1 include:
* Bail if user specifies less guest memory than the restricted DMA pool.
* Avoid silently dropping KVM_VM_TYPE_ARM_PROTECTED on old host kernels.
* Added R-b/T-b tags (thank you!)
The patches are also available here if you want to pull them directly:
https://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git/log/?h=pkvm
Cheers,
Will
Cc: Alexandru Elisei <alexandru.elisei@arm.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Andre Przywara <andre.przywara@arm.com>
Cc: Fuad Tabba <fuad.tabba@linux.dev>
Cc: Oliver Upton <oliver.upton@linux.dev>
Cc: Marc Zyngier <maz@kernel.org>
--->8
Will Deacon (4):
Sync kernel UAPI headers with v7.1
virtio: Factor out base features for modern virtio transports
virtio: Add helper for enabling VIRTIO_F_ACCESS_PLATFORM
arm64: Add support for protected VMs
arm64/fdt.c | 37 ++++++++++++++++++--
arm64/include/asm/kvm.h | 1 +
arm64/include/kvm/fdt-arch.h | 10 +++++-
arm64/include/kvm/kvm-arch.h | 2 ++
arm64/include/kvm/kvm-config-arch.h | 5 ++-
arm64/kvm.c | 28 +++++++++++++--
arm64/pci.c | 2 ++
include/kvm/virtio.h | 2 ++
include/linux/kvm.h | 53 +++++++++++++++++++++++++----
include/linux/virtio_ring.h | 5 +--
riscv/include/asm/kvm.h | 11 +++---
virtio/core.c | 12 +++++++
virtio/mmio-modern.c | 2 +-
virtio/pci-modern.c | 2 +-
x86/include/asm/kvm.h | 21 +++++++-----
15 files changed, 163 insertions(+), 30 deletions(-)
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 kvmtool 1/4] Sync kernel UAPI headers with v7.1
2026-06-25 17:10 [PATCH v2 kvmtool 0/4] Add support for running protected VMs on arm64 Will Deacon
@ 2026-06-25 17:10 ` Will Deacon
2026-06-25 17:10 ` [PATCH v2 kvmtool 2/4] virtio: Factor out base features for modern virtio transports Will Deacon
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Will Deacon @ 2026-06-25 17:10 UTC (permalink / raw)
To: kvm
Cc: kvmarm, Will Deacon, Alexandru Elisei, Suzuki K Poulose,
Andre Przywara, Fuad Tabba, Oliver Upton, Marc Zyngier
Generated using util/update_headers.sh.
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Signed-off-by: Will Deacon <will@kernel.org>
---
arm64/include/asm/kvm.h | 1 +
include/linux/kvm.h | 53 ++++++++++++++++++++++++++++++++-----
include/linux/virtio_ring.h | 5 +---
riscv/include/asm/kvm.h | 11 +++++---
x86/include/asm/kvm.h | 21 +++++++++------
5 files changed, 69 insertions(+), 22 deletions(-)
diff --git a/arm64/include/asm/kvm.h b/arm64/include/asm/kvm.h
index a792a59..1c13bfa 100644
--- a/arm64/include/asm/kvm.h
+++ b/arm64/include/asm/kvm.h
@@ -428,6 +428,7 @@ enum {
#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
#define KVM_DEV_ARM_ITS_CTRL_RESET 4
+#define KVM_DEV_ARM_VGIC_USERSPACE_PPIS 5
/* Device Control API on vcpu fd */
#define KVM_ARM_VCPU_PMU_V3_CTRL 0
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index dddb781..6c8afa2 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -11,9 +11,14 @@
#include <linux/const.h>
#include <linux/types.h>
#include <linux/compiler.h>
+#include <linux/stddef.h>
#include <linux/ioctl.h>
#include <asm/kvm.h>
+#ifdef __KERNEL__
+#include <linux/kvm_types.h>
+#endif
+
#define KVM_API_VERSION 12
/*
@@ -135,6 +140,12 @@ struct kvm_xen_exit {
} u;
};
+struct kvm_exit_snp_req_certs {
+ __u64 gpa;
+ __u64 npages;
+ __u64 ret;
+};
+
#define KVM_S390_GET_SKEYS_NONE 1
#define KVM_S390_SKEYS_MAX 1048576
@@ -180,6 +191,8 @@ struct kvm_xen_exit {
#define KVM_EXIT_MEMORY_FAULT 39
#define KVM_EXIT_TDX 40
#define KVM_EXIT_ARM_SEA 41
+#define KVM_EXIT_ARM_LDST64B 42
+#define KVM_EXIT_SNP_REQ_CERTS 43
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
@@ -402,7 +415,7 @@ struct kvm_run {
} eoi;
/* KVM_EXIT_HYPERV */
struct kvm_hyperv_exit hyperv;
- /* KVM_EXIT_ARM_NISV */
+ /* KVM_EXIT_ARM_NISV / KVM_EXIT_ARM_LDST64B */
struct {
__u64 esr_iss;
__u64 fault_ipa;
@@ -482,6 +495,8 @@ struct kvm_run {
__u64 gva;
__u64 gpa;
} arm_sea;
+ /* KVM_EXIT_SNP_REQ_CERTS */
+ struct kvm_exit_snp_req_certs snp_req_certs;
/* Fix the size of the union. */
char padding[256];
};
@@ -528,7 +543,7 @@ struct kvm_coalesced_mmio {
struct kvm_coalesced_mmio_ring {
__u32 first, last;
- struct kvm_coalesced_mmio coalesced_mmio[];
+ __DECLARE_FLEX_ARRAY(struct kvm_coalesced_mmio, coalesced_mmio);
};
#define KVM_COALESCED_MMIO_MAX \
@@ -578,7 +593,7 @@ struct kvm_clear_dirty_log {
/* for KVM_SET_SIGNAL_MASK */
struct kvm_signal_mask {
__u32 len;
- __u8 sigset[];
+ __DECLARE_FLEX_ARRAY(__u8, sigset);
};
/* for KVM_TPR_ACCESS_REPORTING */
@@ -689,6 +704,11 @@ struct kvm_enable_cap {
#define KVM_VM_TYPE_ARM_IPA_SIZE_MASK 0xffULL
#define KVM_VM_TYPE_ARM_IPA_SIZE(x) \
((x) & KVM_VM_TYPE_ARM_IPA_SIZE_MASK)
+
+#define KVM_VM_TYPE_ARM_PROTECTED (1UL << 31)
+#define KVM_VM_TYPE_ARM_MASK (KVM_VM_TYPE_ARM_IPA_SIZE_MASK | \
+ KVM_VM_TYPE_ARM_PROTECTED)
+
/*
* ioctls for /dev/kvm fds:
*/
@@ -974,6 +994,8 @@ struct kvm_enable_cap {
#define KVM_CAP_GUEST_MEMFD_FLAGS 244
#define KVM_CAP_ARM_SEA_TO_USER 245
#define KVM_CAP_S390_USER_OPEREXEC 246
+#define KVM_CAP_S390_KEYOP 247
+#define KVM_CAP_S390_VSIE_ESAMODE 248
struct kvm_irq_routing_irqchip {
__u32 irqchip;
@@ -1036,7 +1058,7 @@ struct kvm_irq_routing_entry {
struct kvm_irq_routing {
__u32 nr;
__u32 flags;
- struct kvm_irq_routing_entry entries[];
+ __DECLARE_FLEX_ARRAY(struct kvm_irq_routing_entry, entries);
};
#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0)
@@ -1127,7 +1149,7 @@ struct kvm_dirty_tlb {
struct kvm_reg_list {
__u64 n; /* number of regs */
- __u64 reg[];
+ __DECLARE_FLEX_ARRAY(__u64, reg);
};
struct kvm_one_reg {
@@ -1209,6 +1231,10 @@ enum kvm_device_type {
#define KVM_DEV_TYPE_LOONGARCH_EIOINTC KVM_DEV_TYPE_LOONGARCH_EIOINTC
KVM_DEV_TYPE_LOONGARCH_PCHPIC,
#define KVM_DEV_TYPE_LOONGARCH_PCHPIC KVM_DEV_TYPE_LOONGARCH_PCHPIC
+ KVM_DEV_TYPE_LOONGARCH_DMSINTC,
+#define KVM_DEV_TYPE_LOONGARCH_DMSINTC KVM_DEV_TYPE_LOONGARCH_DMSINTC
+ KVM_DEV_TYPE_ARM_VGIC_V5,
+#define KVM_DEV_TYPE_ARM_VGIC_V5 KVM_DEV_TYPE_ARM_VGIC_V5
KVM_DEV_TYPE_MAX,
@@ -1219,6 +1245,16 @@ struct kvm_vfio_spapr_tce {
__s32 tablefd;
};
+#define KVM_S390_KEYOP_ISKE 0x01
+#define KVM_S390_KEYOP_RRBE 0x02
+#define KVM_S390_KEYOP_SSKE 0x03
+struct kvm_s390_keyop {
+ __u64 guest_addr;
+ __u8 key;
+ __u8 operation;
+ __u8 pad[6];
+};
+
/*
* KVM_CREATE_VCPU receives as a parameter the vcpu slot, and returns
* a vcpu fd.
@@ -1238,6 +1274,7 @@ struct kvm_vfio_spapr_tce {
#define KVM_S390_UCAS_MAP _IOW(KVMIO, 0x50, struct kvm_s390_ucas_mapping)
#define KVM_S390_UCAS_UNMAP _IOW(KVMIO, 0x51, struct kvm_s390_ucas_mapping)
#define KVM_S390_VCPU_FAULT _IOW(KVMIO, 0x52, unsigned long)
+#define KVM_S390_KEYOP _IOWR(KVMIO, 0x53, struct kvm_s390_keyop)
/* Device model IOC */
#define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60)
@@ -1579,7 +1616,11 @@ struct kvm_stats_desc {
__u16 size;
__u32 offset;
__u32 bucket_size;
- char name[];
+#ifdef __KERNEL__
+ char name[KVM_STATS_NAME_SIZE];
+#else
+ __DECLARE_FLEX_ARRAY(char, name);
+#endif
};
#define KVM_GET_STATS_FD _IO(KVMIO, 0xce)
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h
index f8c20d3..3c47858 100644
--- a/include/linux/virtio_ring.h
+++ b/include/linux/virtio_ring.h
@@ -31,9 +31,6 @@
* SUCH DAMAGE.
*
* Copyright Rusty Russell IBM Corporation 2007. */
-#ifndef __KERNEL__
-#include <stdint.h>
-#endif
#include <linux/types.h>
#include <linux/virtio_types.h>
@@ -202,7 +199,7 @@ static inline void vring_init(struct vring *vr, unsigned int num, void *p,
vr->num = num;
vr->desc = p;
vr->avail = (struct vring_avail *)((char *)p + num * sizeof(struct vring_desc));
- vr->used = (void *)(((uintptr_t)&vr->avail->ring[num] + sizeof(__virtio16)
+ vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(__virtio16)
+ align-1) & ~(align - 1));
}
diff --git a/riscv/include/asm/kvm.h b/riscv/include/asm/kvm.h
index 54f3ad7..504e733 100644
--- a/riscv/include/asm/kvm.h
+++ b/riscv/include/asm/kvm.h
@@ -110,6 +110,10 @@ struct kvm_riscv_timer {
__u64 state;
};
+/* Possible states for kvm_riscv_timer */
+#define KVM_RISCV_TIMER_STATE_OFF 0
+#define KVM_RISCV_TIMER_STATE_ON 1
+
/*
* ISA extension IDs specific to KVM. This is not the same as the host ISA
* extension IDs as that is internal to the host and should not be exposed
@@ -192,6 +196,9 @@ enum KVM_RISCV_ISA_EXT_ID {
KVM_RISCV_ISA_EXT_ZFBFMIN,
KVM_RISCV_ISA_EXT_ZVFBFMIN,
KVM_RISCV_ISA_EXT_ZVFBFWMA,
+ KVM_RISCV_ISA_EXT_ZCLSD,
+ KVM_RISCV_ISA_EXT_ZILSD,
+ KVM_RISCV_ISA_EXT_ZALASR,
KVM_RISCV_ISA_EXT_MAX,
};
@@ -235,10 +242,6 @@ struct kvm_riscv_sbi_fwft {
struct kvm_riscv_sbi_fwft_feature pointer_masking;
};
-/* Possible states for kvm_riscv_timer */
-#define KVM_RISCV_TIMER_STATE_OFF 0
-#define KVM_RISCV_TIMER_STATE_ON 1
-
/* If you need to interpret the index values, here is the key: */
#define KVM_REG_RISCV_TYPE_MASK 0x00000000FF000000
#define KVM_REG_RISCV_TYPE_SHIFT 24
diff --git a/x86/include/asm/kvm.h b/x86/include/asm/kvm.h
index 7ceff65..5f2b30d 100644
--- a/x86/include/asm/kvm.h
+++ b/x86/include/asm/kvm.h
@@ -197,13 +197,13 @@ struct kvm_msrs {
__u32 nmsrs; /* number of msrs in entries */
__u32 pad;
- struct kvm_msr_entry entries[];
+ __DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries);
};
/* for KVM_GET_MSR_INDEX_LIST */
struct kvm_msr_list {
__u32 nmsrs; /* number of msrs in entries */
- __u32 indices[];
+ __DECLARE_FLEX_ARRAY(__u32, indices);
};
/* Maximum size of any access bitmap in bytes */
@@ -245,7 +245,7 @@ struct kvm_cpuid_entry {
struct kvm_cpuid {
__u32 nent;
__u32 padding;
- struct kvm_cpuid_entry entries[];
+ __DECLARE_FLEX_ARRAY(struct kvm_cpuid_entry, entries);
};
struct kvm_cpuid_entry2 {
@@ -267,7 +267,7 @@ struct kvm_cpuid_entry2 {
struct kvm_cpuid2 {
__u32 nent;
__u32 padding;
- struct kvm_cpuid_entry2 entries[];
+ __DECLARE_FLEX_ARRAY(struct kvm_cpuid_entry2, entries);
};
/* for KVM_GET_PIT and KVM_SET_PIT */
@@ -398,7 +398,7 @@ struct kvm_xsave {
* the contents of CPUID leaf 0xD on the host.
*/
__u32 region[1024];
- __u32 extra[];
+ __DECLARE_FLEX_ARRAY(__u32, extra);
};
#define KVM_MAX_XCRS 16
@@ -476,6 +476,7 @@ struct kvm_sync_regs {
#define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7)
#define KVM_X86_QUIRK_STUFF_FEATURE_MSRS (1 << 8)
#define KVM_X86_QUIRK_IGNORE_GUEST_PAT (1 << 9)
+#define KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM (1 << 10)
#define KVM_STATE_NESTED_FORMAT_VMX 0
#define KVM_STATE_NESTED_FORMAT_SVM 1
@@ -503,6 +504,7 @@ struct kvm_sync_regs {
#define KVM_X86_GRP_SEV 1
# define KVM_X86_SEV_VMSA_FEATURES 0
# define KVM_X86_SNP_POLICY_BITS 1
+# define KVM_X86_SEV_SNP_REQ_CERTS 2
struct kvm_vmx_nested_state_data {
__u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
@@ -564,7 +566,7 @@ struct kvm_pmu_event_filter {
__u32 fixed_counter_bitmap;
__u32 flags;
__u32 pad[4];
- __u64 events[];
+ __DECLARE_FLEX_ARRAY(__u64, events);
};
#define KVM_PMU_EVENT_ALLOW 0
@@ -743,6 +745,7 @@ enum sev_cmd_id {
KVM_SEV_SNP_LAUNCH_START = 100,
KVM_SEV_SNP_LAUNCH_UPDATE,
KVM_SEV_SNP_LAUNCH_FINISH,
+ KVM_SEV_SNP_ENABLE_REQ_CERTS,
KVM_SEV_NR_MAX,
};
@@ -914,8 +917,10 @@ struct kvm_sev_snp_launch_finish {
__u64 pad1[4];
};
-#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
-#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1)
+#define KVM_X2APIC_API_USE_32BIT_IDS _BITULL(0)
+#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK _BITULL(1)
+#define KVM_X2APIC_ENABLE_SUPPRESS_EOI_BROADCAST _BITULL(2)
+#define KVM_X2APIC_DISABLE_SUPPRESS_EOI_BROADCAST _BITULL(3)
struct kvm_hyperv_eventfd {
__u32 conn_id;
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 kvmtool 2/4] virtio: Factor out base features for modern virtio transports
2026-06-25 17:10 [PATCH v2 kvmtool 0/4] Add support for running protected VMs on arm64 Will Deacon
2026-06-25 17:10 ` [PATCH v2 kvmtool 1/4] Sync kernel UAPI headers with v7.1 Will Deacon
@ 2026-06-25 17:10 ` Will Deacon
2026-06-25 17:10 ` [PATCH v2 kvmtool 3/4] virtio: Add helper for enabling VIRTIO_F_ACCESS_PLATFORM Will Deacon
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Will Deacon @ 2026-06-25 17:10 UTC (permalink / raw)
To: kvm
Cc: kvmarm, Will Deacon, Alexandru Elisei, Suzuki K Poulose,
Andre Przywara, Fuad Tabba, Oliver Upton, Marc Zyngier
In preparation for optionally enabling VIRTIO_F_ACCESS_PLATFORM,
factor out the base features for modern virtio transports.
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
---
include/kvm/virtio.h | 1 +
virtio/core.c | 7 +++++++
virtio/mmio-modern.c | 2 +-
virtio/pci-modern.c | 2 +-
4 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/include/kvm/virtio.h b/include/kvm/virtio.h
index 8b7ec1b..c95183b 100644
--- a/include/kvm/virtio.h
+++ b/include/kvm/virtio.h
@@ -277,5 +277,6 @@ void virtio_vhost_reset_vring(struct kvm *kvm, int vhost_fd, u32 index,
int virtio_vhost_set_features(int vhost_fd, u64 features);
int virtio_transport_parser(const struct option *opt, const char *arg, int unset);
+u64 virtio_get_modern_transport_features(void);
#endif /* KVM__VIRTIO_H */
diff --git a/virtio/core.c b/virtio/core.c
index 50c9ddd..8c5086d 100644
--- a/virtio/core.c
+++ b/virtio/core.c
@@ -353,6 +353,13 @@ bool virtio_access_config(struct kvm *kvm, struct virtio_device *vdev,
return true;
}
+static u64 virtio_modern_transport_features = 1ULL << VIRTIO_F_VERSION_1;
+
+u64 virtio_get_modern_transport_features(void)
+{
+ return virtio_modern_transport_features;
+}
+
int virtio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
struct virtio_ops *ops, enum virtio_trans trans,
int device_id, int subsys_id, int class)
diff --git a/virtio/mmio-modern.c b/virtio/mmio-modern.c
index 6c0bb38..7787508 100644
--- a/virtio/mmio-modern.c
+++ b/virtio/mmio-modern.c
@@ -11,7 +11,7 @@ static void virtio_mmio_config_in(struct kvm_cpu *vcpu,
struct virtio_device *vdev)
{
struct virtio_mmio *vmmio = vdev->virtio;
- u64 features = 1ULL << VIRTIO_F_VERSION_1;
+ u64 features = virtio_get_modern_transport_features();
u32 val = 0;
switch (addr) {
diff --git a/virtio/pci-modern.c b/virtio/pci-modern.c
index ef2f3e2..888afa5 100644
--- a/virtio/pci-modern.c
+++ b/virtio/pci-modern.c
@@ -148,7 +148,7 @@ static bool virtio_pci__common_read(struct virtio_device *vdev,
{
u32 val;
struct virtio_pci *vpci = vdev->virtio;
- u64 features = 1ULL << VIRTIO_F_VERSION_1;
+ u64 features = virtio_get_modern_transport_features();
switch (offset - VPCI_CFG_COMMON_START) {
case VIRTIO_PCI_COMMON_DFSELECT:
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 kvmtool 3/4] virtio: Add helper for enabling VIRTIO_F_ACCESS_PLATFORM
2026-06-25 17:10 [PATCH v2 kvmtool 0/4] Add support for running protected VMs on arm64 Will Deacon
2026-06-25 17:10 ` [PATCH v2 kvmtool 1/4] Sync kernel UAPI headers with v7.1 Will Deacon
2026-06-25 17:10 ` [PATCH v2 kvmtool 2/4] virtio: Factor out base features for modern virtio transports Will Deacon
@ 2026-06-25 17:10 ` Will Deacon
2026-06-25 17:10 ` [PATCH v2 kvmtool 4/4] arm64: Add support for protected VMs Will Deacon
2026-06-25 19:42 ` [PATCH v2 kvmtool 0/4] Add support for running protected VMs on arm64 Fuad Tabba
4 siblings, 0 replies; 6+ messages in thread
From: Will Deacon @ 2026-06-25 17:10 UTC (permalink / raw)
To: kvm
Cc: kvmarm, Will Deacon, Alexandru Elisei, Suzuki K Poulose,
Andre Przywara, Fuad Tabba, Oliver Upton, Marc Zyngier
In preparation for supporting protected guests on arm64, introduce a
virtio helper to advertise the VIRTIO_F_ACCESS_PLATFORM feature for the
modern transport.
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
---
include/kvm/virtio.h | 1 +
virtio/core.c | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/include/kvm/virtio.h b/include/kvm/virtio.h
index c95183b..dd3117b 100644
--- a/include/kvm/virtio.h
+++ b/include/kvm/virtio.h
@@ -277,6 +277,7 @@ void virtio_vhost_reset_vring(struct kvm *kvm, int vhost_fd, u32 index,
int virtio_vhost_set_features(int vhost_fd, u64 features);
int virtio_transport_parser(const struct option *opt, const char *arg, int unset);
+void virtio_modern_enable_feat_access_platform(void);
u64 virtio_get_modern_transport_features(void);
#endif /* KVM__VIRTIO_H */
diff --git a/virtio/core.c b/virtio/core.c
index 8c5086d..96bbf96 100644
--- a/virtio/core.c
+++ b/virtio/core.c
@@ -355,6 +355,11 @@ bool virtio_access_config(struct kvm *kvm, struct virtio_device *vdev,
static u64 virtio_modern_transport_features = 1ULL << VIRTIO_F_VERSION_1;
+void virtio_modern_enable_feat_access_platform(void)
+{
+ virtio_modern_transport_features |= 1ULL << VIRTIO_F_ACCESS_PLATFORM;
+}
+
u64 virtio_get_modern_transport_features(void)
{
return virtio_modern_transport_features;
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 kvmtool 4/4] arm64: Add support for protected VMs
2026-06-25 17:10 [PATCH v2 kvmtool 0/4] Add support for running protected VMs on arm64 Will Deacon
` (2 preceding siblings ...)
2026-06-25 17:10 ` [PATCH v2 kvmtool 3/4] virtio: Add helper for enabling VIRTIO_F_ACCESS_PLATFORM Will Deacon
@ 2026-06-25 17:10 ` Will Deacon
2026-06-25 19:42 ` [PATCH v2 kvmtool 0/4] Add support for running protected VMs on arm64 Fuad Tabba
4 siblings, 0 replies; 6+ messages in thread
From: Will Deacon @ 2026-06-25 17:10 UTC (permalink / raw)
To: kvm
Cc: kvmarm, Will Deacon, Alexandru Elisei, Suzuki K Poulose,
Andre Przywara, Fuad Tabba, Oliver Upton, Marc Zyngier
Introduce a new '--protected' parameter which requests the creation of
a protected VM type from the kernel. In addition, a reserved DMA region
is advertised in the device-tree and VIRTIO_F_ACCESS_PLATFORM is
advertised so that virtio transfers can be bounced through a shared
memory window.
Signed-off-by: Will Deacon <will@kernel.org>
---
arm64/fdt.c | 37 +++++++++++++++++++++++++++--
arm64/include/kvm/fdt-arch.h | 10 +++++++-
arm64/include/kvm/kvm-arch.h | 2 ++
arm64/include/kvm/kvm-config-arch.h | 5 +++-
arm64/kvm.c | 28 ++++++++++++++++++++--
arm64/pci.c | 2 ++
6 files changed, 78 insertions(+), 6 deletions(-)
diff --git a/arm64/fdt.c b/arm64/fdt.c
index 98f1dd9..3cbd36e 100644
--- a/arm64/fdt.c
+++ b/arm64/fdt.c
@@ -71,6 +71,19 @@ static void generate_irq_prop(void *fdt, u8 irq, enum irq_type irq_type)
_FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
}
+static bool emit_dma_regions;
+void generate_dma_region_prop(void *fdt)
+{
+ if (emit_dma_regions)
+ _FDT(fdt_property_cell(fdt, "memory-region", PHANDLE_DMA));
+}
+
+static void generate_aux_props(void *fdt, u8 irq, enum irq_type irq_type)
+{
+ generate_irq_prop(fdt, irq, irq_type);
+ generate_dma_region_prop(fdt);
+}
+
struct psci_fns {
u32 cpu_suspend;
u32 cpu_off;
@@ -103,7 +116,7 @@ static int setup_fdt(struct kvm *kvm)
{
struct device_header *dev_hdr;
u8 staging_fdt[FDT_MAX_SIZE];
- u64 mem_reg_prop[] = {
+ u64 resv_mem_prop, mem_reg_prop[] = {
cpu_to_fdt64(kvm->arch.memory_guest_start),
cpu_to_fdt64(kvm->ram_size),
};
@@ -116,6 +129,9 @@ static int setup_fdt(struct kvm *kvm)
void (*generate_cpu_peripheral_fdt_nodes)(void *, struct kvm *)
= kvm->cpus[0]->generate_fdt_nodes;
+ /* Generate DMA regions for bouncing in protected VMs */
+ emit_dma_regions = kvm->cfg.arch.protected;
+
/* Create new tree without a reserve map */
_FDT(fdt_create(fdt, FDT_MAX_SIZE));
_FDT(fdt_finish_reservemap(fdt));
@@ -162,6 +178,23 @@ static int setup_fdt(struct kvm *kvm)
_FDT(fdt_property(fdt, "reg", mem_reg_prop, sizeof(mem_reg_prop)));
_FDT(fdt_end_node(fdt));
+ /* Reserved memory (restricted DMA pool) */
+ if (emit_dma_regions) {
+ _FDT(fdt_begin_node(fdt, "reserved-memory"));
+ _FDT(fdt_property_cell(fdt, "#address-cells", 0x2));
+ _FDT(fdt_property_cell(fdt, "#size-cells", 0x2));
+ _FDT(fdt_property(fdt, "ranges", NULL, 0));
+
+ _FDT(fdt_begin_node(fdt, "restricted_dma_reserved"));
+ _FDT(fdt_property_string(fdt, "compatible", "restricted-dma-pool"));
+ resv_mem_prop = cpu_to_fdt64(DMA_MEM_REGION_SIZE);
+ _FDT(fdt_property(fdt, "size", &resv_mem_prop, sizeof(resv_mem_prop)));
+ _FDT(fdt_property_cell(fdt, "phandle", PHANDLE_DMA));
+ _FDT(fdt_end_node(fdt));
+
+ _FDT(fdt_end_node(fdt));
+ }
+
/* CPU and peripherals (interrupt controller, timers, etc) */
generate_cpu_nodes(fdt, kvm);
if (generate_cpu_peripheral_fdt_nodes)
@@ -172,7 +205,7 @@ static int setup_fdt(struct kvm *kvm)
while (dev_hdr) {
generate_mmio_fdt_nodes = dev_hdr->data;
if (generate_mmio_fdt_nodes) {
- generate_mmio_fdt_nodes(fdt, dev_hdr, generate_irq_prop);
+ generate_mmio_fdt_nodes(fdt, dev_hdr, generate_aux_props);
} else {
pr_debug("Missing FDT node generator for MMIO device %d",
dev_hdr->dev_num);
diff --git a/arm64/include/kvm/fdt-arch.h b/arm64/include/kvm/fdt-arch.h
index 60c2d40..8a0a460 100644
--- a/arm64/include/kvm/fdt-arch.h
+++ b/arm64/include/kvm/fdt-arch.h
@@ -1,6 +1,14 @@
#ifndef ARM__FDT_H
#define ARM__FDT_H
-enum phandles {PHANDLE_RESERVED = 0, PHANDLE_GIC, PHANDLE_MSI, PHANDLES_MAX};
+enum phandles {
+ PHANDLE_RESERVED = 0,
+ PHANDLE_GIC,
+ PHANDLE_MSI,
+ PHANDLE_DMA,
+ PHANDLES_MAX
+};
+
+void generate_dma_region_prop(void *fdt);
#endif /* ARM__FDT_H */
diff --git a/arm64/include/kvm/kvm-arch.h b/arm64/include/kvm/kvm-arch.h
index a50e6a4..e7dd526 100644
--- a/arm64/include/kvm/kvm-arch.h
+++ b/arm64/include/kvm/kvm-arch.h
@@ -87,6 +87,8 @@
#define MAX_PAGE_SIZE SZ_64K
+/* Size of DMA region for bouncing when running a protected guest */
+#define DMA_MEM_REGION_SIZE SZ_32M
static inline bool arm_addr_in_ioport_region(u64 phys_addr)
{
diff --git a/arm64/include/kvm/kvm-config-arch.h b/arm64/include/kvm/kvm-config-arch.h
index d321b77..c2702d5 100644
--- a/arm64/include/kvm/kvm-config-arch.h
+++ b/arm64/include/kvm/kvm-config-arch.h
@@ -19,6 +19,7 @@ struct kvm_config_arch {
unsigned int sve_max_vq;
bool no_pvtime;
bool psci;
+ bool protected;
};
int irqchip_parser(const struct option *opt, const char *arg, int unset);
@@ -70,6 +71,8 @@ int sve_vl_parser(const struct option *opt, const char *arg, int unset);
OPT_BOOLEAN('\0', "nested", &(cfg)->nested_virt, \
"Start VCPUs in EL2 (for nested virt)"), \
OPT_BOOLEAN('\0', "e2h0", &(cfg)->e2h0, \
- "Create guest without VHE support"),
+ "Create guest without VHE support"), \
+ OPT_BOOLEAN('\0', "protected", &(cfg)->protected, \
+ "Create a protected VM when pKVM is enabled"),
#endif /* ARM_COMMON__KVM_CONFIG_ARCH_H */
diff --git a/arm64/kvm.c b/arm64/kvm.c
index c8570ce..fb0b98d 100644
--- a/arm64/kvm.c
+++ b/arm64/kvm.c
@@ -6,6 +6,7 @@
#include "kvm/fdt.h"
#include "kvm/gic.h"
#include "kvm/kvm-cpu.h"
+#include "kvm/virtio.h"
#include "asm/smccc.h"
@@ -147,6 +148,9 @@ void kvm__arch_init(struct kvm *kvm)
kvm__arch_enable_mte(kvm);
kvm__setup_smccc(kvm);
kvm__arch_set_counter_offset(kvm);
+
+ if (kvm->cfg.arch.protected)
+ virtio_modern_enable_feat_access_platform();
}
@@ -463,6 +467,22 @@ void kvm__arch_validate_cfg(struct kvm *kvm)
if (kvm->cfg.arch.e2h0 && !kvm->cfg.arch.nested_virt)
pr_warning("--e2h0 requires --nested, ignoring");
+
+ if (kvm->cfg.arch.protected) {
+ if (kvm->cfg.ram_size &&
+ kvm->cfg.ram_size < DMA_MEM_REGION_SIZE) {
+ die("RAM size (0x%llx) smaller than DMA bounce region (0x%x)",
+ kvm->cfg.ram_size, DMA_MEM_REGION_SIZE);
+ }
+
+ if (kvm->cfg.virtio_transport == VIRTIO_MMIO_LEGACY ||
+ kvm->cfg.virtio_transport == VIRTIO_PCI_LEGACY) {
+ die("Protected VMs require a modern virtio transport");
+ }
+
+ if (kvm->cfg.balloon)
+ die("Ballooning not supported with protected VMs");
+ }
}
u64 kvm__arch_default_ram_address(void)
@@ -485,11 +505,15 @@ int kvm__get_vm_type(struct kvm *kvm)
{
unsigned int ipa_bits, max_ipa_bits;
unsigned long max_ipa;
+ int type = 0;
+
+ if (kvm->cfg.arch.protected)
+ type |= KVM_VM_TYPE_ARM_PROTECTED;
/* If we're running on an old kernel, use 0 as the VM type */
max_ipa_bits = kvm__arch_get_ipa_limit(kvm);
if (!max_ipa_bits)
- return 0;
+ return type;
/* Otherwise, compute the minimal required IPA size */
max_ipa = kvm->cfg.ram_addr + kvm->cfg.ram_size - 1;
@@ -500,7 +524,7 @@ int kvm__get_vm_type(struct kvm *kvm)
if (ipa_bits > max_ipa_bits)
die("Memory too large for this system (needs %d bits, %d available)", ipa_bits, max_ipa_bits);
- return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
+ return type | KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
}
static int kvm__arch_free_kernel_header(struct kvm *kvm)
diff --git a/arm64/pci.c b/arm64/pci.c
index 0366783..db87db8 100644
--- a/arm64/pci.c
+++ b/arm64/pci.c
@@ -73,6 +73,8 @@ void pci__generate_fdt_nodes(void *fdt, struct kvm *kvm)
if (irqchip == IRQCHIP_GICV2M || irqchip == IRQCHIP_GICV3_ITS)
_FDT(fdt_property_cell(fdt, "msi-parent", PHANDLE_MSI));
+ generate_dma_region_prop(fdt);
+
/* Generate the interrupt map ... */
dev_hdr = device__first_dev(DEVICE_BUS_PCI);
while (dev_hdr && nentries < ARRAY_SIZE(irq_map)) {
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 kvmtool 0/4] Add support for running protected VMs on arm64
2026-06-25 17:10 [PATCH v2 kvmtool 0/4] Add support for running protected VMs on arm64 Will Deacon
` (3 preceding siblings ...)
2026-06-25 17:10 ` [PATCH v2 kvmtool 4/4] arm64: Add support for protected VMs Will Deacon
@ 2026-06-25 19:42 ` Fuad Tabba
4 siblings, 0 replies; 6+ messages in thread
From: Fuad Tabba @ 2026-06-25 19:42 UTC (permalink / raw)
To: Will Deacon
Cc: kvm, kvmarm, Alexandru Elisei, Suzuki K Poulose, Andre Przywara,
Oliver Upton, Marc Zyngier
On Thu, 25 Jun 2026 at 18:10, Will Deacon <will@kernel.org> wrote:
>
> Hi folks,
>
> This is v2 of the patches I previously posted here:
>
> https://lore.kernel.org/r/20260619115415.5475-1-will@kernel.org
>
> Changes since v1 include:
>
> * Bail if user specifies less guest memory than the restricted DMA pool.
> * Avoid silently dropping KVM_VM_TYPE_ARM_PROTECTED on old host kernels.
> * Added R-b/T-b tags (thank you!)
>
> The patches are also available here if you want to pull them directly:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git/log/?h=pkvm
>
> Cheers,
>
> Will
For the new series:
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Tested-by: Fuad Tabba < fuad.tabba@linux.dev>
Cheers,
/fuad
>
> Cc: Alexandru Elisei <alexandru.elisei@arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
> Cc: Andre Przywara <andre.przywara@arm.com>
> Cc: Fuad Tabba <fuad.tabba@linux.dev>
> Cc: Oliver Upton <oliver.upton@linux.dev>
> Cc: Marc Zyngier <maz@kernel.org>
>
> --->8
>
> Will Deacon (4):
> Sync kernel UAPI headers with v7.1
> virtio: Factor out base features for modern virtio transports
> virtio: Add helper for enabling VIRTIO_F_ACCESS_PLATFORM
> arm64: Add support for protected VMs
>
> arm64/fdt.c | 37 ++++++++++++++++++--
> arm64/include/asm/kvm.h | 1 +
> arm64/include/kvm/fdt-arch.h | 10 +++++-
> arm64/include/kvm/kvm-arch.h | 2 ++
> arm64/include/kvm/kvm-config-arch.h | 5 ++-
> arm64/kvm.c | 28 +++++++++++++--
> arm64/pci.c | 2 ++
> include/kvm/virtio.h | 2 ++
> include/linux/kvm.h | 53 +++++++++++++++++++++++++----
> include/linux/virtio_ring.h | 5 +--
> riscv/include/asm/kvm.h | 11 +++---
> virtio/core.c | 12 +++++++
> virtio/mmio-modern.c | 2 +-
> virtio/pci-modern.c | 2 +-
> x86/include/asm/kvm.h | 21 +++++++-----
> 15 files changed, 163 insertions(+), 30 deletions(-)
>
> --
> 2.55.0.rc0.799.gd6f94ed593-goog
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-06-25 19:43 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-25 17:10 [PATCH v2 kvmtool 0/4] Add support for running protected VMs on arm64 Will Deacon
2026-06-25 17:10 ` [PATCH v2 kvmtool 1/4] Sync kernel UAPI headers with v7.1 Will Deacon
2026-06-25 17:10 ` [PATCH v2 kvmtool 2/4] virtio: Factor out base features for modern virtio transports Will Deacon
2026-06-25 17:10 ` [PATCH v2 kvmtool 3/4] virtio: Add helper for enabling VIRTIO_F_ACCESS_PLATFORM Will Deacon
2026-06-25 17:10 ` [PATCH v2 kvmtool 4/4] arm64: Add support for protected VMs Will Deacon
2026-06-25 19:42 ` [PATCH v2 kvmtool 0/4] Add support for running protected VMs on arm64 Fuad Tabba
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox