Re: KVM: x86: handle idiv overflow at kvm_write_tsc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jun 11, 2013 at 11:31:12PM -0300, Marcelo Tosatti wrote:
> 
> Its possible that idivl overflows (due to large delta stored in usdiff,
> valid scenario).
> 
> Create an exception handler to catch the overflow exception (division by zero
> is protected by vcpu->arch.virtual_tsc_khz check), and interpret it accordingly
> (delta is larger than USEC_PER_SEC).
> 
> Fixes https://bugzilla.redhat.com/show_bug.cgi?id=969644
> 
> Signed-off-by: Marcelo Tosatti <mtosatti@xxxxxxxxxx>
> 
Applied, thanks.

> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 094b5d9..64a4b03 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -1194,20 +1194,37 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
>  	elapsed = ns - kvm->arch.last_tsc_nsec;
>  
>  	if (vcpu->arch.virtual_tsc_khz) {
> +		int faulted = 0;
> +
>  		/* 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;
>  #else
>  		/* do_div() only does unsigned */
> -		asm("idivl %2; xor %%edx, %%edx"
> -		: "=A"(usdiff)
> -		: "A"(usdiff * 1000), "rm"(vcpu->arch.virtual_tsc_khz));
> +		asm("1: idivl %[divisor]\n"
> +		    "2: xor %%edx, %%edx\n"
> +		    "   movl $0, %[faulted]\n"
> +		    "3:\n"
> +		    ".section .fixup,\"ax\"\n"
> +		    "4: movl $1, %[faulted]\n"
> +		    "   jmp  3b\n"
> +		    ".previous\n"
> +
> +		_ASM_EXTABLE(1b, 4b)
> +
> +		: "=A"(usdiff), [faulted] "=r" (faulted)
> +		: "A"(usdiff * 1000), [divisor] "rm"(vcpu->arch.virtual_tsc_khz));
> +
>  #endif
>  		do_div(elapsed, 1000);
>  		usdiff -= elapsed;
>  		if (usdiff < 0)
>  			usdiff = -usdiff;
> +
> +		/* idivl overflow => difference is larger than USEC_PER_SEC */
> +		if (faulted)
> +			usdiff = USEC_PER_SEC;
>  	} else
>  		usdiff = USEC_PER_SEC; /* disable TSC match window below */
>  
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux