mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-25 02:40:54 +07:00
KVM: introduce kvm->created_vcpus
The race between creating the irqchip and the first VCPU is currently fixed by checking the presence of an irqchip before updating kvm->online_vcpus, and undoing the whole VCPU creation if someone created the irqchip in the meanwhile. Instead, introduce a new field in struct kvm that will count VCPUs under a mutex, without the atomic access and memory ordering that we need elsewhere to protect the vcpus array. This also plugs the race and is more easily applicable in all similar circumstances. Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
682a810887
commit
6c7caebc26
@ -371,7 +371,15 @@ struct kvm {
|
||||
struct srcu_struct srcu;
|
||||
struct srcu_struct irq_srcu;
|
||||
struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
|
||||
|
||||
/*
|
||||
* created_vcpus is protected by kvm->lock, and is incremented
|
||||
* at the beginning of KVM_CREATE_VCPU. online_vcpus is only
|
||||
* incremented after storing the kvm_vcpu pointer in vcpus,
|
||||
* and is accessed atomically.
|
||||
*/
|
||||
atomic_t online_vcpus;
|
||||
int created_vcpus;
|
||||
int last_boosted_vcpu;
|
||||
struct list_head vm_list;
|
||||
struct mutex lock;
|
||||
|
@ -2346,9 +2346,20 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
|
||||
if (id >= KVM_MAX_VCPU_ID)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&kvm->lock);
|
||||
if (kvm->created_vcpus == KVM_MAX_VCPUS) {
|
||||
mutex_unlock(&kvm->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
kvm->created_vcpus++;
|
||||
mutex_unlock(&kvm->lock);
|
||||
|
||||
vcpu = kvm_arch_vcpu_create(kvm, id);
|
||||
if (IS_ERR(vcpu))
|
||||
return PTR_ERR(vcpu);
|
||||
if (IS_ERR(vcpu)) {
|
||||
r = PTR_ERR(vcpu);
|
||||
goto vcpu_decrement;
|
||||
}
|
||||
|
||||
preempt_notifier_init(&vcpu->preempt_notifier, &kvm_preempt_ops);
|
||||
|
||||
@ -2361,10 +2372,6 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
|
||||
r = -EINVAL;
|
||||
goto unlock_vcpu_destroy;
|
||||
}
|
||||
if (atomic_read(&kvm->online_vcpus) == KVM_MAX_VCPUS) {
|
||||
r = -EINVAL;
|
||||
goto unlock_vcpu_destroy;
|
||||
}
|
||||
if (kvm_get_vcpu_by_id(kvm, id)) {
|
||||
r = -EEXIST;
|
||||
goto unlock_vcpu_destroy;
|
||||
@ -2397,6 +2404,10 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
|
||||
mutex_unlock(&kvm->lock);
|
||||
vcpu_destroy:
|
||||
kvm_arch_vcpu_destroy(vcpu);
|
||||
vcpu_decrement:
|
||||
mutex_lock(&kvm->lock);
|
||||
kvm->created_vcpus--;
|
||||
mutex_unlock(&kvm->lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user