aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2013-03-18 12:54:32 -0400
committerMarcelo Tosatti <mtosatti@redhat.com>2013-03-18 17:03:39 -0400
commitc09664bb44184b3846e8c5254db4eae4b932682a (patch)
treee37f7b8a0840008d3bb4f73f79ee71f4cf8df6c3 /arch/x86
parentf445f11eb2cc265dd47da5b2e864df46cd6e5a82 (diff)
KVM: x86: fix deadlock in clock-in-progress request handling
There is a deadlock in pvclock handling: cpu0: cpu1: kvm_gen_update_masterclock() kvm_guest_time_update() spin_lock(pvclock_gtod_sync_lock) local_irq_save(flags) spin_lock(pvclock_gtod_sync_lock) kvm_make_mclock_inprogress_request(kvm) make_all_cpus_request() smp_call_function_many() Now if smp_call_function_many() called by cpu0 tries to call function on cpu1 there will be a deadlock. Fix by moving pvclock_gtod_sync_lock protected section outside irq disabled section. Analyzed by Gleb Natapov <gleb@redhat.com> Acked-by: Gleb Natapov <gleb@redhat.com> Reported-and-Tested-by: Yongjie Ren <yongjie.ren@intel.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/x86.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f71500af1f81..f7c850b36910 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1416,15 +1416,6 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
1416 kernel_ns = 0; 1416 kernel_ns = 0;
1417 host_tsc = 0; 1417 host_tsc = 0;
1418 1418
1419 /* Keep irq disabled to prevent changes to the clock */
1420 local_irq_save(flags);
1421 this_tsc_khz = __get_cpu_var(cpu_tsc_khz);
1422 if (unlikely(this_tsc_khz == 0)) {
1423 local_irq_restore(flags);
1424 kvm_make_request(KVM_REQ_CLOCK_UPDATE, v);
1425 return 1;
1426 }
1427
1428 /* 1419 /*
1429 * If the host uses TSC clock, then passthrough TSC as stable 1420 * If the host uses TSC clock, then passthrough TSC as stable
1430 * to the guest. 1421 * to the guest.
@@ -1436,6 +1427,15 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
1436 kernel_ns = ka->master_kernel_ns; 1427 kernel_ns = ka->master_kernel_ns;
1437 } 1428 }
1438 spin_unlock(&ka->pvclock_gtod_sync_lock); 1429 spin_unlock(&ka->pvclock_gtod_sync_lock);
1430
1431 /* Keep irq disabled to prevent changes to the clock */
1432 local_irq_save(flags);
1433 this_tsc_khz = __get_cpu_var(cpu_tsc_khz);
1434 if (unlikely(this_tsc_khz == 0)) {
1435 local_irq_restore(flags);
1436 kvm_make_request(KVM_REQ_CLOCK_UPDATE, v);
1437 return 1;
1438 }
1439 if (!use_master_clock) { 1439 if (!use_master_clock) {
1440 host_tsc = native_read_tsc(); 1440 host_tsc = native_read_tsc();
1441 kernel_ns = get_kernel_ns(); 1441 kernel_ns = get_kernel_ns();