[PATCH 11/60] kvm: Introduce struct kvm_vcpu_common
From: Jörg Rödel
Date: Mon Jun 08 2026 - 11:02:11 EST
From: Joerg Roedel <joerg.roedel@xxxxxxx>
When creating one VCPU object per plane there is still a lot of VCPU
state which needes to be shared across all planes. Create struct
kvm_vcpu_common as a container for this shared state.
Co-developed-by: Carlos López <clopez@xxxxxxx>
Signed-off-by: Joerg Roedel <joerg.roedel@xxxxxxx>
---
include/linux/kvm_host.h | 10 ++++++++++
virt/kvm/kvm_main.c | 36 ++++++++++++++++++++++++++++++++++--
2 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 5a72f73a2f31..c4c4922df965 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -322,6 +322,13 @@ struct kvm_mmio_fragment {
unsigned int len;
};
+struct kvm_vcpu_common {
+ struct kvm *kvm;
+
+ /* Currently active VCPU */
+ struct kvm_vcpu *current_vcpu;
+};
+
struct kvm_vcpu {
struct kvm *kvm;
struct kvm_plane *plane;
@@ -400,6 +407,9 @@ struct kvm_vcpu {
*/
struct kvm_memory_slot *last_used_slot;
u64 last_used_slot_gen;
+
+ struct kvm_vcpu_common *common;
+ unsigned plane_level;
};
/*
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 668645dd3945..fb840d029c56 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -438,6 +438,20 @@ void *kvm_mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc)
}
#endif
+static int kvm_vcpu_init_common(struct kvm_vcpu *vcpu, struct kvm *kvm)
+{
+ struct kvm_vcpu_common *common = kzalloc(sizeof(*common), GFP_KERNEL_ACCOUNT);
+
+ if (common == NULL)
+ return -ENOMEM;
+
+ common->kvm = kvm;
+ common->current_vcpu = vcpu;
+ vcpu->common = common;
+
+ return 0;
+}
+
static void kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
{
mutex_init(&vcpu->mutex);
@@ -459,14 +473,26 @@ static void kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
preempt_notifier_init(&vcpu->preempt_notifier, &kvm_preempt_ops);
vcpu->last_used_slot = NULL;
+ vcpu->plane_level = 0;
+
/* Fill the stats id string for the vcpu */
snprintf(vcpu->stats_id, sizeof(vcpu->stats_id), "kvm-%d/vcpu-%d",
task_pid_nr(current), id);
}
+static void kvm_vcpu_common_destroy(struct kvm_vcpu *vcpu)
+{
+ if (vcpu->plane_level == 0)
+ kfree(vcpu->common);
+
+ vcpu->common = NULL;
+}
+
static void kvm_vcpu_destroy(struct kvm_vcpu *vcpu)
{
kvm_arch_vcpu_destroy(vcpu);
+
+ kvm_vcpu_common_destroy(vcpu);
kvm_dirty_ring_free(&vcpu->dirty_ring);
/*
@@ -1360,8 +1386,8 @@ static void kvm_destroy_vm(struct kvm *kvm)
#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
xa_destroy(&kvm->mem_attr_array);
#endif
- kvm_arch_free_vm(kvm);
kvm_destroy_planes(kvm);
+ kvm_arch_free_vm(kvm);
preempt_notifier_dec();
kvm_disable_virtualization();
mmdrop(mm);
@@ -4246,11 +4272,15 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, unsigned long id)
goto vcpu_decrement;
}
+ r = kvm_vcpu_init_common(vcpu, kvm);
+ if (r)
+ goto vcpu_free;
+
BUILD_BUG_ON(sizeof(struct kvm_run) > PAGE_SIZE);
page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
if (!page) {
r = -ENOMEM;
- goto vcpu_free;
+ goto vcpu_free_common;
}
vcpu->run = page_address(page);
@@ -4318,6 +4348,8 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, unsigned long id)
kvm_arch_vcpu_destroy(vcpu);
vcpu_free_run_page:
free_page((unsigned long)vcpu->run);
+vcpu_free_common:
+ kvm_vcpu_common_destroy(vcpu);
vcpu_free:
kmem_cache_free(kvm_vcpu_cache, vcpu);
vcpu_decrement:
--
2.53.0