When the VM is created, we initialize the flag to track the start of a dirty quota migration as false. It is set to true when the dirty quota migration starts. When a vCPU is created, we allocate memory for the dirty quota context of the vCPU. This dirty quota context is mmaped to QEMU when a dirty quota migration starts. Co-developed-by: Anurag Madnawat <anurag.madnawat@xxxxxxxxxxx> Signed-off-by: Anurag Madnawat <anurag.madnawat@xxxxxxxxxxx> Signed-off-by: Shivam Kumar <shivam.kumar1@xxxxxxxxxxx> Signed-off-by: Shaju Abraham <shaju.abraham@xxxxxxxxxxx> Signed-off-by: Manish Mishra <manish.mishra@xxxxxxxxxxx> --- arch/x86/kvm/Makefile | 3 ++- include/linux/dirty_quota_migration.h | 2 ++ virt/kvm/dirty_quota_migration.c | 14 ++++++++++++++ virt/kvm/kvm_main.c | 6 ++++++ 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 virt/kvm/dirty_quota_migration.c diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 75dfd27b6e8a..a26fc0c94a83 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -11,7 +11,8 @@ KVM := ../../../virt/kvm kvm-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ $(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o \ - $(KVM)/dirty_ring.o $(KVM)/binary_stats.o + $(KVM)/dirty_ring.o $(KVM)/binary_stats.o \ + $(KVM)/dirty_quota_migration.o kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o kvm-y += x86.o emulate.o i8259.o irq.o lapic.o \ diff --git a/include/linux/dirty_quota_migration.h b/include/linux/dirty_quota_migration.h index 6338cb6984df..2d6e5cd17be6 100644 --- a/include/linux/dirty_quota_migration.h +++ b/include/linux/dirty_quota_migration.h @@ -8,4 +8,6 @@ struct vCPUDirtyQuotaContext { u64 dirty_quota; }; +int kvm_vcpu_dirty_quota_alloc(struct vCPUDirtyQuotaContext **vCPUdqctx); + #endif /* DIRTY_QUOTA_MIGRATION_H */ diff --git a/virt/kvm/dirty_quota_migration.c b/virt/kvm/dirty_quota_migration.c new file mode 100644 index 000000000000..262f071aac0c --- /dev/null +++ b/virt/kvm/dirty_quota_migration.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/dirty_quota_migration.h> + +int kvm_vcpu_dirty_quota_alloc(struct vCPUDirtyQuotaContext **vCPUdqctx) +{ + u64 size = sizeof(struct vCPUDirtyQuotaContext); + *vCPUdqctx = vmalloc(size); + if (!(*vCPUdqctx)) + return -ENOMEM; + memset((*vCPUdqctx), 0, size); + return 0; +} diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 7851f3a1b5f7..f232a16a26e7 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -66,6 +66,7 @@ #include <trace/events/kvm.h> #include <linux/kvm_dirty_ring.h> +#include <linux/dirty_quota_migration.h> /* Worst case buffer size needed for holding an integer. */ #define ITOA_MAX_LEN 12 @@ -1071,6 +1072,7 @@ static struct kvm *kvm_create_vm(unsigned long type) } kvm->max_halt_poll_ns = halt_poll_ns; + kvm->dirty_quota_migration_enabled = false; r = kvm_arch_init_vm(kvm, type); if (r) @@ -3630,6 +3632,10 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id) goto arch_vcpu_destroy; } + r = kvm_vcpu_dirty_quota_alloc(&vcpu->vCPUdqctx); + if (r) + goto arch_vcpu_destroy; + mutex_lock(&kvm->lock); if (kvm_get_vcpu_by_id(kvm, id)) { r = -EEXIST; -- 2.22.3