From patchwork Fri Aug 20 08:07:44 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zachary Amsden X-Patchwork-Id: 120514 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o7K8BbSh003307 for ; Fri, 20 Aug 2010 08:11:37 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752369Ab0HTIJS (ORCPT ); Fri, 20 Aug 2010 04:09:18 -0400 Received: from mx1.redhat.com ([209.132.183.28]:31902 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752357Ab0HTIJP (ORCPT ); Fri, 20 Aug 2010 04:09:15 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o7K89BL2004896 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 20 Aug 2010 04:09:11 -0400 Received: from mysore (vpn-9-158.rdu.redhat.com [10.11.9.158]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o7K87qfO027969; Fri, 20 Aug 2010 04:09:09 -0400 From: Zachary Amsden To: kvm@vger.kernel.org Cc: Zachary Amsden , Avi Kivity , Marcelo Tosatti , Glauber Costa , Thomas Gleixner , John Stultz , linux-kernel@vger.kernel.org Subject: [KVM timekeeping 30/35] IOCTL for setting TSC rate Date: Thu, 19 Aug 2010 22:07:44 -1000 Message-Id: <1282291669-25709-31-git-send-email-zamsden@redhat.com> In-Reply-To: <1282291669-25709-1-git-send-email-zamsden@redhat.com> References: <1282291669-25709-1-git-send-email-zamsden@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Fri, 20 Aug 2010 08:11:37 +0000 (UTC) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 887e30f..e618265 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1017,6 +1017,10 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) kvm_x86_ops->adjust_tsc_offset(v, tsc-tsc_timestamp); local_irq_restore(flags); + /* hw_tsc_khz unknown at creation time, check for overrun */ + if (this_tsc_khz > v->kvm->arch.virtual_tsc_khz) + vcpu->tsc_overrun = 1; + /* Now, see if we need to switch into trap mode */ if (vcpu->tsc_overrun && !vcpu->tsc_trapping) kvm_x86_ops->set_tsc_trap(v, 1); @@ -1846,6 +1850,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_DEBUGREGS: case KVM_CAP_X86_ROBUST_SINGLESTEP: case KVM_CAP_XSAVE: + case KVM_CAP_SET_TSC_RATE: r = 1; break; case KVM_CAP_COALESCED_MMIO: @@ -3413,6 +3418,37 @@ long kvm_arch_vm_ioctl(struct file *filp, r = 0; break; } + case KVM_X86_GET_TSC_RATE: { + u32 rate = kvm->arch.virtual_tsc_khz; + r = -EFAULT; + if (copy_to_user(argp, &rate, sizeof(rate))) + goto out; + r = 0; + break; + } + case KVM_X86_SET_TSC_RATE: { + u32 rate; + int i; + struct kvm_vcpu *vcpu; + r = -EFAULT; + if (copy_from_user(&rate, argp, sizeof rate)) + goto out; + if (rate == 0 || rate > (1ULL << 40)) { + r = -EINVAL; + break; + } + /* + * This is intended to be called once, during VM creation. + * Calling this with running VCPUs to dynamically change + * speed is risky; there is no synchronization with the + * compensation loop, so computations using virtual_tsc_khz + * conversions may go haywire. Use at your own risk. + */ + kvm_arch_set_tsc_khz(kvm, rate); + kvm_for_each_vcpu(i, vcpu, kvm) + kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); + break; + } default: ; diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 3707704..22d27f2 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -539,6 +539,7 @@ struct kvm_ppc_pvinfo { #define KVM_CAP_XCRS 56 #endif #define KVM_CAP_PPC_GET_PVINFO 57 +#define KVM_CAP_SET_TSC_RATE 58 #ifdef KVM_CAP_IRQ_ROUTING @@ -675,6 +676,9 @@ struct kvm_clock_data { #define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2) /* Available with KVM_CAP_PPC_GET_PVINFO */ #define KVM_PPC_GET_PVINFO _IOW(KVMIO, 0xa1, struct kvm_ppc_pvinfo) +/* Available with KVM_CAP_SET_TSC_RATE */ +#define KVM_X86_GET_TSC_RATE _IOR(KVMIO, 0xa2, __u32) +#define KVM_X86_SET_TSC_RATE _IOW(KVMIO, 0xa3, __u32) /* * ioctls for vcpu fds