From patchwork Thu Jan 6 10:10:45 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zachary Amsden X-Patchwork-Id: 458311 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p06ABq9Q026491 for ; Thu, 6 Jan 2011 10:11:52 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752540Ab1AFKLG (ORCPT ); Thu, 6 Jan 2011 05:11:06 -0500 Received: from mx1.redhat.com ([209.132.183.28]:25122 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752469Ab1AFKLF (ORCPT ); Thu, 6 Jan 2011 05:11:05 -0500 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.13.8/8.13.8) with ESMTP id p06AB4M9016221 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 6 Jan 2011 05:11:05 -0500 Received: from mysore (vpn-9-192.rdu.redhat.com [10.11.9.192]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p06AAmou021959; Thu, 6 Jan 2011 05:11:03 -0500 From: Zachary Amsden To: kvm@vger.kernel.org Cc: Zachary Amsden , linux-kernel@vger.kernel.org Subject: [KVM TSC trapping / migration 2/2] Add TSC KHZ MSR Date: Thu, 6 Jan 2011 00:10:45 -1000 Message-Id: <1294308645-31113-3-git-send-email-zamsden@redhat.com> In-Reply-To: <1294308645-31113-1-git-send-email-zamsden@redhat.com> References: <1294308645-31113-1-git-send-email-zamsden@redhat.com> To: Avi Kivity , Marcelo Tosatti , Glauber Costa X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 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.6 (demeter1.kernel.org [140.211.167.41]); Thu, 06 Jan 2011 10:11:52 +0000 (UTC) diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 7b562b6..723e60d 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -32,6 +32,7 @@ /* Custom MSRs falls in the range 0x4b564d00-0x4b564dff */ #define MSR_KVM_WALL_CLOCK_NEW 0x4b564d00 #define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01 +#define MSR_KVM_TSC_KHZ 0x4b564d02 #define KVM_MAX_MMU_OP_BATCH 32 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index bbcd582..ff5addc 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -786,10 +786,11 @@ EXPORT_SYMBOL_GPL(kvm_get_dr); * kvm-specific. Those are put in the beginning of the list. */ -#define KVM_SAVE_MSRS_BEGIN 7 +#define KVM_SAVE_MSRS_BEGIN 8 static u32 msrs_to_save[] = { MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW, + MSR_KVM_TSC_KHZ, HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL, HV_X64_MSR_APIC_ASSIST_PAGE, MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, @@ -1608,6 +1609,25 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) } break; } + case MSR_KVM_TSC_KHZ: { + struct kvm_arch *arch = &vcpu->kvm->arch; + /* + * If userspace indicates a fixed rate TSC, accept attempts + * to set the TSC rate to support incoming migrations. + * This is a write once MSR, to prevent guest tampering. + */ + if (arch->tsc_flags & KVM_TSC_FLAG_KHZ_MSR_WRITABLE) { + if (data > KVM_TSC_MAX_KHZ || data < KVM_TSC_MIN_KHZ) + return 1; + + spin_lock(&arch->clock_lock); + kvm_arch_set_tsc_khz(vcpu->kvm, data); + kvm_setup_tsc_trapping(vcpu); + arch->tsc_flags &= ~KVM_TSC_FLAG_KHZ_MSR_WRITABLE; + spin_unlock(&arch->clock_lock); + } + break; + } case MSR_IA32_MCG_CTL: case MSR_IA32_MCG_STATUS: case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1: @@ -1884,6 +1904,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) case MSR_KVM_SYSTEM_TIME_NEW: data = vcpu->arch.time; break; + case MSR_KVM_TSC_KHZ: + data = vcpu->kvm->arch.virtual_tsc_khz; + break; case MSR_IA32_P5_MC_ADDR: case MSR_IA32_P5_MC_TYPE: case MSR_IA32_MCG_CAP: @@ -3615,7 +3638,8 @@ long kvm_arch_vm_ioctl(struct file *filp, r = -EINVAL; if (user_tsc.flags & ~(KVM_TSC_FLAG_FIXED_RATE | - KVM_TSC_FLAG_SMP_COHERENCY)) + KVM_TSC_FLAG_SMP_COHERENCY | + KVM_TSC_FLAG_KHZ_MSR_WRITABLE)) goto out; if (user_tsc.tsc_khz && diff --git a/include/linux/kvm.h b/include/linux/kvm.h index cb97e53..0e316d8 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -628,6 +628,7 @@ struct kvm_tsc_control { #define KVM_TSC_FLAG_FIXED_RATE (1 << 0) #define KVM_TSC_FLAG_SMP_COHERENCY (1 << 1) +#define KVM_TSC_FLAG_KHZ_MSR_WRITABLE (1 << 2) #define KVM_TSC_MIN_KHZ 16000 /* 16 MHz, slower than first Pentium */ #define KVM_TSC_MAX_KHZ 100000000 /* 100 GHz, good for a few years */