Skip to content

Commit

Permalink
KVM: x86: disable preemption around the call to kvm_arch_vcpu_{un|}bl…
Browse files Browse the repository at this point in the history
…ocking

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 <[email protected]>
Message-Id: <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
Maxim Levitsky authored and bonzini committed Jun 9, 2022
1 parent 66c768d commit 18869f2
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions virt/kvm/kvm_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3328,9 +3328,11 @@ bool kvm_vcpu_block(struct kvm_vcpu *vcpu)

vcpu->stat.generic.blocking = 1;

preempt_disable();
kvm_arch_vcpu_blocking(vcpu);

prepare_to_rcuwait(wait);
preempt_enable();

for (;;) {
set_current_state(TASK_INTERRUPTIBLE);

Expand All @@ -3340,9 +3342,11 @@ bool kvm_vcpu_block(struct kvm_vcpu *vcpu)
waited = true;
schedule();
}
finish_rcuwait(wait);

preempt_disable();
finish_rcuwait(wait);
kvm_arch_vcpu_unblocking(vcpu);
preempt_enable();

vcpu->stat.generic.blocking = 0;

Expand Down

0 comments on commit 18869f2

Please sign in to comment.