KVM: x86: do not report a vCPU as preempted outside instruction boundaries
authorPaolo Bonzini <pbonzini@redhat.com>
Tue, 7 Jun 2022 14:09:03 +0000 (10:09 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 Aug 2022 11:07:51 +0000 (13:07 +0200)
commit92343314d34e04da0923cefd3be67521d706fa35
tree1d50df69306cc9de300d62dd8ad4781dee743440
parent3d4c28475ee352c440b83484b72b1320ff76364a
KVM: x86: do not report a vCPU as preempted outside instruction boundaries

[ Upstream commit 6cd88243c7e03845a450795e134b488fc2afb736 ]

If a vCPU is outside guest mode and is scheduled out, it might be in the
process of making a memory access.  A problem occurs if another vCPU uses
the PV TLB flush feature during the period when the vCPU is scheduled
out, and a virtual address has already been translated but has not yet
been accessed, because this is equivalent to using a stale TLB entry.

To avoid this, only report a vCPU as preempted if sure that the guest
is at an instruction boundary.  A rescheduling request will be delivered
to the host physical CPU as an external interrupt, so for simplicity
consider any vmexit *not* instruction boundary except for external
interrupts.

It would in principle be okay to report the vCPU as preempted also
if it is sleeping in kvm_vcpu_block(): a TLB flush IPI will incur the
vmentry/vmexit overhead unnecessarily, and optimistic spinning is
also unlikely to succeed.  However, leave it for later because right
now kvm_vcpu_check_block() is doing memory accesses.  Even
though the TLB flush issue only applies to virtual memory address,
it's very much preferrable to be conservative.

Reported-by: Jann Horn <jannh@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/svm/svm.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.c