Skip to contentSkip to conversation

Patch "KVM: arm/arm64: vgic: Fix deadlock on error handling" has been added to the 4.9-stable tree

PATCH [email protected] 1 participant 1 message Jan 23, 2017 Stable branch

lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

KVM: arm/arm64: vgic: Fix deadlock on error handling

to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
kvm-arm-arm64-vgic-fix-deadlock-on-error-handling.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 1193e6aeecb36c74c48c7cd0f641acbbed9ddeef Mon Sep 17 00:00:00 2001

From: Marc Zyngier <[email protected]>
Date: Thu, 12 Jan 2017 09:21:56 +0000
Subject: KVM: arm/arm64: vgic: Fix deadlock on error handling

From: Marc Zyngier <[email protected]>

commit 1193e6aeecb36c74c48c7cd0f641acbbed9ddeef upstream.

Dmitry Vyukov reported that the syzkaller fuzzer triggered a deadlock in the vgic setup code when an error was detected, as the cleanup code tries to take a lock that is already held by the setup code.

The fix is to avoid retaking the lock when cleaning up, by telling the cleanup function that we already hold it.

---
 virt/kvm/arm/vgic/vgic-init.c |   18 +++++++++++++-----
 virt/kvm/arm/vgic/vgic-v2.c   |    2 --
 virt/kvm/arm/vgic/vgic-v3.c   |    2 --
 3 files changed, 13 insertions(+), 9 deletions(-)
virt/kvm/arm/vgic/vgic-init.c +13 -5
@@ -268,15 +268,11 @@ static void kvm_vgic_dist_destroy(struct
 {
 	struct vgic_dist *dist = &kvm->arch.vgic;
 
-	mutex_lock(&kvm->lock);
-
 	dist->ready = false;
 	dist->initialized = false;
 
 	kfree(dist->spis);
 	dist->nr_spis = 0;
-
-	mutex_unlock(&kvm->lock);
 }
 
 void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
@@ -286,7 +282,8 @@ void kvm_vgic_vcpu_destroy(struct kvm_vc
 	INIT_LIST_HEAD(&vgic_cpu->ap_list_head);
 }
 
-void kvm_vgic_destroy(struct kvm *kvm)
+/* To be called with kvm->lock held */
+static void __kvm_vgic_destroy(struct kvm *kvm)
 {
 	struct kvm_vcpu *vcpu;
 	int i;
@@ -297,6 +294,13 @@ void kvm_vgic_destroy(struct kvm *kvm)
 		kvm_vgic_vcpu_destroy(vcpu);
 }
 
+void kvm_vgic_destroy(struct kvm *kvm)
+{
+	mutex_lock(&kvm->lock);
+	__kvm_vgic_destroy(kvm);
+	mutex_unlock(&kvm->lock);
+}
+
 /**
  * vgic_lazy_init: Lazy init is only allowed if the GIC exposed to the guest
  * is a GICv2. A GICv3 must be explicitly initialized by the guest using the
@@ -348,6 +352,10 @@ int kvm_vgic_map_resources(struct kvm *k
 		ret = vgic_v2_map_resources(kvm);
 	else
 		ret = vgic_v3_map_resources(kvm);
+
+	if (ret)
+		__kvm_vgic_destroy(kvm);
+
 out:
 	mutex_unlock(&kvm->lock);
 	return ret;
virt/kvm/arm/vgic/vgic-v2.c +0 -2
@@ -293,8 +293,6 @@ int vgic_v2_map_resources(struct kvm *kv
 	dist->ready = true;
 
 out:
-	if (ret)
-		kvm_vgic_destroy(kvm);
 	return ret;
 }
 
virt/kvm/arm/vgic/vgic-v3.c +0 -2
@@ -302,8 +302,6 @@ int vgic_v3_map_resources(struct kvm *kv
 	dist->ready = true;
 
 out:
-	if (ret)
-		kvm_vgic_destroy(kvm);
 	return ret;
 }
 

Patches currently in stable-queue which might be from [email protected] are

queue-4.9/kvm-arm-arm64-vgic-fix-deadlock-on-error-handling.patch