Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a937f96 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

KVM: protect kvm_usage_count with its own spinlock



The VM list need not be protected by a raw spinlock.  Separate the
two so that kvm_lock can be made non-raw.

Cc: kvm@vger.kernel.org
Cc: gleb@redhat.com
Cc: jan.kiszka@siemens.com
Reviewed-by: default avatarGleb Natapov <gleb@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 4fa92fb2
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -135,7 +135,11 @@ Name: kvm_lock
Type:		raw_spinlock
Type:		raw_spinlock
Arch:		any
Arch:		any
Protects:	- vm_list
Protects:	- vm_list
		- hardware virtualization enable/disable

Name:		kvm_count_lock
Type:		raw_spinlock_t
Arch:		any
Protects:	- hardware virtualization enable/disable
Comment:	'raw' because hardware enabling/disabling must be atomic /wrt
Comment:	'raw' because hardware enabling/disabling must be atomic /wrt
		migration.
		migration.


+10 −9
Original line number Original line Diff line number Diff line
@@ -71,6 +71,7 @@ MODULE_LICENSE("GPL");
 */
 */


DEFINE_RAW_SPINLOCK(kvm_lock);
DEFINE_RAW_SPINLOCK(kvm_lock);
static DEFINE_RAW_SPINLOCK(kvm_count_lock);
LIST_HEAD(vm_list);
LIST_HEAD(vm_list);


static cpumask_var_t cpus_hardware_enabled;
static cpumask_var_t cpus_hardware_enabled;
@@ -2683,10 +2684,10 @@ static void hardware_enable_nolock(void *junk)


static void hardware_enable(void)
static void hardware_enable(void)
{
{
	raw_spin_lock(&kvm_lock);
	raw_spin_lock(&kvm_count_lock);
	if (kvm_usage_count)
	if (kvm_usage_count)
		hardware_enable_nolock(NULL);
		hardware_enable_nolock(NULL);
	raw_spin_unlock(&kvm_lock);
	raw_spin_unlock(&kvm_count_lock);
}
}


static void hardware_disable_nolock(void *junk)
static void hardware_disable_nolock(void *junk)
@@ -2701,10 +2702,10 @@ static void hardware_disable_nolock(void *junk)


static void hardware_disable(void)
static void hardware_disable(void)
{
{
	raw_spin_lock(&kvm_lock);
	raw_spin_lock(&kvm_count_lock);
	if (kvm_usage_count)
	if (kvm_usage_count)
		hardware_disable_nolock(NULL);
		hardware_disable_nolock(NULL);
	raw_spin_unlock(&kvm_lock);
	raw_spin_unlock(&kvm_count_lock);
}
}


static void hardware_disable_all_nolock(void)
static void hardware_disable_all_nolock(void)
@@ -2718,16 +2719,16 @@ static void hardware_disable_all_nolock(void)


static void hardware_disable_all(void)
static void hardware_disable_all(void)
{
{
	raw_spin_lock(&kvm_lock);
	raw_spin_lock(&kvm_count_lock);
	hardware_disable_all_nolock();
	hardware_disable_all_nolock();
	raw_spin_unlock(&kvm_lock);
	raw_spin_unlock(&kvm_count_lock);
}
}


static int hardware_enable_all(void)
static int hardware_enable_all(void)
{
{
	int r = 0;
	int r = 0;


	raw_spin_lock(&kvm_lock);
	raw_spin_lock(&kvm_count_lock);


	kvm_usage_count++;
	kvm_usage_count++;
	if (kvm_usage_count == 1) {
	if (kvm_usage_count == 1) {
@@ -2740,7 +2741,7 @@ static int hardware_enable_all(void)
		}
		}
	}
	}


	raw_spin_unlock(&kvm_lock);
	raw_spin_unlock(&kvm_count_lock);


	return r;
	return r;
}
}
@@ -3130,7 +3131,7 @@ static int kvm_suspend(void)
static void kvm_resume(void)
static void kvm_resume(void)
{
{
	if (kvm_usage_count) {
	if (kvm_usage_count) {
		WARN_ON(raw_spin_is_locked(&kvm_lock));
		WARN_ON(raw_spin_is_locked(&kvm_count_lock));
		hardware_enable_nolock(NULL);
		hardware_enable_nolock(NULL);
	}
	}
}
}