summaryrefslogtreecommitdiff
authorChristoffer Dall <christoffer.dall@arm.com>2018-07-03 20:54:14 (GMT)
committer Greg Kroah-Hartman <gregkh@linuxfoundation.org>2018-09-26 06:36:34 (GMT)
commit0a10ce961bb34a0a42e60534479d8a79fc46d927 (patch)
treed875555e6619c85b132e3bd99ffd3b81895a3cdf
parentf51c345732ef8e3983b64aaf65b833e14b233ba7 (diff)
downloadcommon-0a10ce961bb34a0a42e60534479d8a79fc46d927.zip
common-0a10ce961bb34a0a42e60534479d8a79fc46d927.tar.gz
common-0a10ce961bb34a0a42e60534479d8a79fc46d927.tar.bz2
KVM: arm/arm64: Fix vgic init race
[ Upstream commit 1d47191de7e15900f8fbfe7cccd7c6e1c2d7c31a ] The vgic_init function can race with kvm_arch_vcpu_create() which does not hold kvm_lock() and we therefore have no synchronization primitives to ensure we're doing the right thing. As the user is trying to initialize or run the VM while at the same time creating more VCPUs, we just have to refuse to initialize the VGIC in this case rather than silently failing with a broken VCPU. Reviewed-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Christoffer Dall <christoffer.dall@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat
-rw-r--r--virt/kvm/arm/vgic/vgic-init.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
index 539d3f5..80d8888 100644
--- a/virt/kvm/arm/vgic/vgic-init.c
+++ b/virt/kvm/arm/vgic/vgic-init.c
@@ -241,6 +241,10 @@ int vgic_init(struct kvm *kvm)
if (vgic_initialized(kvm))
return 0;
+ /* Are we also in the middle of creating a VCPU? */
+ if (kvm->created_vcpus != atomic_read(&kvm->online_vcpus))
+ return -EBUSY;
+
/* freeze the number of spis */
if (!dist->nr_spis)
dist->nr_spis = VGIC_NR_IRQS_LEGACY - VGIC_NR_PRIVATE_IRQS;