]> git.baikalelectronics.ru Git - kernel.git/commit
KVM: x86: APICv: fix race in kvm_request_apicv_update on SVM
authorMaxim Levitsky <mlevitsk@redhat.com>
Tue, 10 Aug 2021 20:52:44 +0000 (23:52 +0300)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 20 Aug 2021 20:06:23 +0000 (16:06 -0400)
commit5cba0a0ba5840dd8db23c99fbbcf3218053c7c5c
tree7b173443c856a5d4b6999bc6fc88c4b94dac1c5c
parent5556fae75143625191fab21511428c9ac54f3808
KVM: x86: APICv: fix race in kvm_request_apicv_update on SVM

Currently on SVM, the kvm_request_apicv_update toggles the APICv
memslot without doing any synchronization.

If there is a mismatch between that memslot state and the AVIC state,
on one of the vCPUs, an APIC mmio access can be lost:

For example:

VCPU0: enable the APIC_ACCESS_PAGE_PRIVATE_MEMSLOT
VCPU1: access an APIC mmio register.

Since AVIC is still disabled on VCPU1, the access will not be intercepted
by it, and neither will it cause MMIO fault, but rather it will just be
read/written from/to the dummy page mapped into the
APIC_ACCESS_PAGE_PRIVATE_MEMSLOT.

Fix that by adding a lock guarding the AVIC state changes, and carefully
order the operations of kvm_request_apicv_update to avoid this race:

1. Take the lock
2. Send KVM_REQ_APICV_UPDATE
3. Update the apic inhibit reason
4. Release the lock

This ensures that at (2) all vCPUs are kicked out of the guest mode,
but don't yet see the new avic state.
Then only after (4) all other vCPUs can update their AVIC state and resume.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
Message-Id: <20210810205251.424103-10-mlevitsk@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/x86.c