From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gleb Natapov Subject: Re: VMX: x86: handle host TSC calibration failure Date: Tue, 12 Mar 2013 13:18:52 +0200 Message-ID: <20130312111851.GW11223@redhat.com> References: <20130312021024.GA21328@amt.cnet> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: kvm@vger.kernel.org, Paolo Bonzini To: Marcelo Tosatti Return-path: Received: from mx1.redhat.com ([209.132.183.28]:10413 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752623Ab3CLLSx (ORCPT ); Tue, 12 Mar 2013 07:18:53 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r2CBIrsJ028520 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 12 Mar 2013 07:18:53 -0400 Content-Disposition: inline In-Reply-To: <20130312021024.GA21328@amt.cnet> Sender: kvm-owner@vger.kernel.org List-ID: On Mon, Mar 11, 2013 at 11:10:24PM -0300, Marcelo Tosatti wrote: > > If the host TSC calibration fails, tsc_khz is zero (see tsc_init.c). > Handle such case properly in KVM (instead of dividing by zero). > > https://bugzilla.redhat.com/show_bug.cgi?id=859282 > > Signed-off-by: Marcelo Tosatti > Fixed small space/tab problem and applied. Thanks. > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 35b4912..19741b9 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -1079,6 +1079,10 @@ static void kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 this_tsc_khz) > u32 thresh_lo, thresh_hi; > int use_scaling = 0; > > + /* tsc_khz can be zero if TSC calibration fails */ > + if (this_tsc_khz == 0) > + return; > + > /* Compute a scale to convert nanoseconds in TSC cycles */ > kvm_get_time_scale(this_tsc_khz, NSEC_PER_SEC / 1000, > &vcpu->arch.virtual_tsc_shift, > @@ -1156,20 +1160,23 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr) > ns = get_kernel_ns(); > elapsed = ns - kvm->arch.last_tsc_nsec; > > - /* n.b - signed multiplication and division required */ > - usdiff = data - kvm->arch.last_tsc_write; > + if (vcpu->arch.virtual_tsc_khz) { > + /* n.b - signed multiplication and division required */ > + usdiff = data - kvm->arch.last_tsc_write; > #ifdef CONFIG_X86_64 > - usdiff = (usdiff * 1000) / vcpu->arch.virtual_tsc_khz; > + usdiff = (usdiff * 1000) / vcpu->arch.virtual_tsc_khz; > #else > - /* do_div() only does unsigned */ > - asm("idivl %2; xor %%edx, %%edx" > - : "=A"(usdiff) > - : "A"(usdiff * 1000), "rm"(vcpu->arch.virtual_tsc_khz)); > + /* do_div() only does unsigned */ > + asm("idivl %2; xor %%edx, %%edx" > + : "=A"(usdiff) > + : "A"(usdiff * 1000), "rm"(vcpu->arch.virtual_tsc_khz)); > #endif > - do_div(elapsed, 1000); > - usdiff -= elapsed; > - if (usdiff < 0) > - usdiff = -usdiff; > + do_div(elapsed, 1000); > + usdiff -= elapsed; > + if (usdiff < 0) > + usdiff = -usdiff; > + } else > + usdiff = USEC_PER_SEC; /* disable TSC match window below */ > > /* > * Special case: TSC write with a small delta (1 second) of virtual -- Gleb.