KVM: x86: disable preemption around the call to kvm_arch_vcpu_{un|}blocking
On SVM, if preemption happens right after the call to finish_rcuwait but before call to kvm_arch_vcpu_unblocking on SVM/AVIC, it itself will re-enable AVIC, and then we will try to re-enable it again in kvm_arch_vcpu_unblocking which will lead to a warning in __avic_vcpu_load. The same problem can happen if the vCPU is preempted right after the call to kvm_arch_vcpu_blocking but before the call to prepare_to_rcuwait and in this case, we will end up with AVIC enabled during sleep - Ooops. Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com> Message-Id: <20220606180829.102503-7-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
66c768d30e
commit
18869f26df
|
@ -3328,9 +3328,11 @@ bool kvm_vcpu_block(struct kvm_vcpu *vcpu)
|
||||||
|
|
||||||
vcpu->stat.generic.blocking = 1;
|
vcpu->stat.generic.blocking = 1;
|
||||||
|
|
||||||
|
preempt_disable();
|
||||||
kvm_arch_vcpu_blocking(vcpu);
|
kvm_arch_vcpu_blocking(vcpu);
|
||||||
|
|
||||||
prepare_to_rcuwait(wait);
|
prepare_to_rcuwait(wait);
|
||||||
|
preempt_enable();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
|
||||||
|
@ -3340,9 +3342,11 @@ bool kvm_vcpu_block(struct kvm_vcpu *vcpu)
|
||||||
waited = true;
|
waited = true;
|
||||||
schedule();
|
schedule();
|
||||||
}
|
}
|
||||||
finish_rcuwait(wait);
|
|
||||||
|
|
||||||
|
preempt_disable();
|
||||||
|
finish_rcuwait(wait);
|
||||||
kvm_arch_vcpu_unblocking(vcpu);
|
kvm_arch_vcpu_unblocking(vcpu);
|
||||||
|
preempt_enable();
|
||||||
|
|
||||||
vcpu->stat.generic.blocking = 0;
|
vcpu->stat.generic.blocking = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue