[PATCH 09/60] kvm: Introduce struct kvm_plane
From: Jörg Rödel
Date: Mon Jun 08 2026 - 11:11:23 EST
From: Paolo Bonzini <pbonzini@xxxxxxxxxx>
Introduce a data structure to keep VM-wide per-plane state. Initialize
the structure with a back-pointer to struct kvm and the plane level
the structure represents.
Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
Co-developed-by: Joerg Roedel <joerg.roedel@xxxxxxx>
Signed-off-by: Joerg Roedel <joerg.roedel@xxxxxxx>
---
include/linux/kvm_host.h | 7 +++++++
include/uapi/linux/kvm.h | 6 ++++++
virt/kvm/kvm_main.c | 41 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 54 insertions(+)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 4c14aee1fb06..5be4c9f118b4 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -767,6 +767,11 @@ struct kvm_memslots {
int node_idx;
};
+struct kvm_plane {
+ struct kvm *kvm;
+ unsigned level;
+};
+
struct kvm {
#ifdef KVM_HAVE_MMU_RWLOCK
rwlock_t mmu_lock;
@@ -806,6 +811,8 @@ struct kvm {
spinlock_t gpc_lock;
struct list_head gpc_list;
+ struct kvm_plane *planes[KVM_MAX_PLANES];
+
/*
* created_vcpus is protected by kvm->lock, and is incremented
* at the beginning of KVM_CREATE_VCPU. online_vcpus is only
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 6c8afa2047bf..813f964a6dc1 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -730,6 +730,11 @@ struct kvm_enable_cap {
#define KVM_GET_EMULATED_CPUID _IOWR(KVMIO, 0x09, struct kvm_cpuid2)
#define KVM_GET_MSR_FEATURE_INDEX_LIST _IOWR(KVMIO, 0x0a, struct kvm_msr_list)
+/*
+ * Maximum number of supported planes
+ */
+#define KVM_MAX_PLANES 16
+
/*
* Extension capability list.
*/
@@ -996,6 +1001,7 @@ struct kvm_enable_cap {
#define KVM_CAP_S390_USER_OPEREXEC 246
#define KVM_CAP_S390_KEYOP 247
#define KVM_CAP_S390_VSIE_ESAMODE 248
+#define KVM_CAP_PLANES 249
struct kvm_irq_routing_irqchip {
__u32 irqchip;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 881f92d7a469..a68469c6d12e 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1095,6 +1095,38 @@ static inline struct kvm_io_bus *kvm_get_bus_for_destruction(struct kvm *kvm,
static int kvm_enable_virtualization(void);
static void kvm_disable_virtualization(void);
+static struct kvm_plane *kvm_create_plane(struct kvm *kvm, unsigned plane_level)
+{
+ struct kvm_plane *plane = kzalloc(sizeof(*plane), GFP_KERNEL_ACCOUNT);
+
+ if (!plane)
+ return NULL;
+
+ plane->kvm = kvm;
+ plane->level = plane_level;
+
+ kvm->planes[plane_level] = plane;
+
+ return plane;
+}
+
+static void kvm_destroy_one_plane(struct kvm_plane *plane)
+{
+ kfree(plane);
+}
+
+static void kvm_destroy_planes(struct kvm *kvm)
+{
+ int i;
+
+ for (i = 0; i < KVM_MAX_PLANES; ++i) {
+ if (kvm->planes[i] == NULL)
+ continue;
+ kvm_destroy_one_plane(kvm->planes[i]);
+ kvm->planes[i] = NULL;
+ }
+}
+
static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
{
struct kvm *kvm = kvm_arch_alloc_vm();
@@ -1127,6 +1159,12 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX);
+ /* Initialize planes array and allocate plane 0 */
+ if (kvm_create_plane(kvm, 0) == NULL) {
+ r = -ENOMEM;
+ goto out_no_planes;
+ }
+
/*
* Force subsequent debugfs file creations to fail if the VM directory
* is not created (by kvm_create_vm_debugfs()).
@@ -1225,6 +1263,8 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
out_err_no_irq_srcu:
cleanup_srcu_struct(&kvm->srcu);
out_err_no_srcu:
+ kvm_destroy_planes(kvm);
+out_no_planes:
kvm_arch_free_vm(kvm);
mmdrop(current->mm);
return ERR_PTR(r);
@@ -1304,6 +1344,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
xa_destroy(&kvm->mem_attr_array);
#endif
kvm_arch_free_vm(kvm);
+ kvm_destroy_planes(kvm);
preempt_notifier_dec();
kvm_disable_virtualization();
mmdrop(mm);
--
2.53.0