diff mbox

[3/6] KVM: X86: Make tsc_delta calculation a function of guest tsc

Message ID 1301042691-22929-4-git-send-email-joerg.roedel@amd.com (mailing list archive)
State New, archived
Headers show

Commit Message

Joerg Roedel March 25, 2011, 8:44 a.m. UTC
None

Comments

Jan Kiszka April 16, 2011, 4:09 p.m. UTC | #1
On 2011-03-25 09:44, Joerg Roedel wrote:
> The calculation of the tsc_delta value to ensure a
> forward-going tsc for the guest is a function of the
> host-tsc. This works as long as the guests tsc_khz is equal
> to the hosts tsc_khz. With tsc-scaling hardware support this
> is not longer true and the tsc_delta needs to be calculated
> using guest_tsc values.
> 
> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
> ---
>  arch/x86/kvm/x86.c |    9 +++++++--
>  1 files changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 1e7af86..47dd6ed 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -2126,8 +2126,13 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>  	kvm_x86_ops->vcpu_load(vcpu, cpu);
>  	if (unlikely(vcpu->cpu != cpu) || check_tsc_unstable()) {
>  		/* Make sure TSC doesn't go backwards */
> -		s64 tsc_delta = !vcpu->arch.last_host_tsc ? 0 :
> -				native_read_tsc() - vcpu->arch.last_host_tsc;
> +		s64 tsc_delta;
> +		u64 tsc;
> +
> +		kvm_get_msr(vcpu, MSR_IA32_TSC, &tsc);
> +		tsc_delta = !vcpu->arch.last_guest_tsc ? 0 :
> +			     tsc - vcpu->arch.last_guest_tsc;
> +
>  		if (tsc_delta < 0)
>  			mark_tsc_unstable("KVM discovered backwards TSC");
>  		if (check_tsc_unstable()) {

This patch appears to cause troubles to Linux guests on TSC clocksource
and APIC highres timer. The first boot after qemu start is always fine,
but after a reboot the guest timer appears to fire incorrectly or even
not at all.

Was this patch tested with a guest reboot scenario as well? Does it
account for the TSC being reset to 0 on reboot?

I'm using a 2.6.38 host + kvm-kmod, but I don't see that this could be
the reason. Going back one kernel commit while keeping kvm-kmod
unchanged resolves the issue.

Jan
diff mbox

Patch

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1e7af86..47dd6ed 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2126,8 +2126,13 @@  void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	kvm_x86_ops->vcpu_load(vcpu, cpu);
 	if (unlikely(vcpu->cpu != cpu) || check_tsc_unstable()) {
 		/* Make sure TSC doesn't go backwards */
-		s64 tsc_delta = !vcpu->arch.last_host_tsc ? 0 :
-				native_read_tsc() - vcpu->arch.last_host_tsc;
+		s64 tsc_delta;
+		u64 tsc;
+
+		kvm_get_msr(vcpu, MSR_IA32_TSC, &tsc);
+		tsc_delta = !vcpu->arch.last_guest_tsc ? 0 :
+			     tsc - vcpu->arch.last_guest_tsc;
+
 		if (tsc_delta < 0)
 			mark_tsc_unstable("KVM discovered backwards TSC");
 		if (check_tsc_unstable()) {