From patchwork Thu May 6 08:45:45 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Dongxiao" X-Patchwork-Id: 97289 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o469wii6017208 for ; Thu, 6 May 2010 09:58:46 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756078Ab0EFIpw (ORCPT ); Thu, 6 May 2010 04:45:52 -0400 Received: from mga14.intel.com ([143.182.124.37]:43176 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751059Ab0EFIpw convert rfc822-to-8bit (ORCPT ); Thu, 6 May 2010 04:45:52 -0400 Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 06 May 2010 01:45:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.52,339,1270450800"; d="scan'208";a="273962210" Received: from pgsmsx601.gar.corp.intel.com ([10.221.43.69]) by azsmga001.ch.intel.com with ESMTP; 06 May 2010 01:45:40 -0700 Received: from shsmsx602.ccr.corp.intel.com (10.239.4.104) by pgsmsx601.gar.corp.intel.com (10.221.43.69) with Microsoft SMTP Server (TLS) id 8.2.176.0; Thu, 6 May 2010 16:45:32 +0800 Received: from shsmsx501.ccr.corp.intel.com ([10.239.4.141]) by SHSMSX602.ccr.corp.intel.com ([10.239.4.104]) with mapi; Thu, 6 May 2010 16:45:31 +0800 From: "Xu, Dongxiao" To: "kvm@vger.kernel.org" CC: Avi Kivity , Marcelo Tosatti , Alexander Graf Date: Thu, 6 May 2010 16:45:45 +0800 Subject: [PATCH 3/3 v2] KVM: VMX: VMXON/VMXOFF usage changes. Thread-Topic: [PATCH 3/3 v2] KVM: VMX: VMXON/VMXOFF usage changes. Thread-Index: Acrs+ISR9yBBbwvHTeulk06tDzWUTw== Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US MIME-Version: 1.0 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]); Thu, 06 May 2010 09:58:46 +0000 (UTC) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index aa3b2f9..85a17a1 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -168,6 +168,9 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) static int init_rmode(struct kvm *kvm); static u64 construct_eptp(unsigned long root_hpa); +static void kvm_cpu_vmxon(u64 addr); +static void kvm_cpu_vmxoff(void); + static DEFINE_PER_CPU(struct vmcs *, vmxarea); static DEFINE_PER_CPU(struct vmcs *, current_vmcs); @@ -787,8 +790,10 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); u64 tsc_this, delta, new_offset; + u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); if (vmm_coexistence) { + kvm_cpu_vmxon(phys_addr); vmcs_load(vmx->vmcs); set_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests); } else { @@ -846,6 +851,7 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu) vmcs_clear(vmx->vmcs); rdtscll(vmx->vcpu.arch.host_tsc); vmx->launched = 0; + kvm_cpu_vmxoff(); } } @@ -1269,9 +1275,11 @@ static int hardware_enable(void *garbage) FEATURE_CONTROL_LOCKED | FEATURE_CONTROL_VMXON_ENABLED); write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug safe */ - kvm_cpu_vmxon(phys_addr); - ept_sync_global(); + if (!vmm_coexistence) { + kvm_cpu_vmxon(phys_addr); + ept_sync_global(); + } return 0; } @@ -1297,9 +1305,10 @@ static void kvm_cpu_vmxoff(void) static void hardware_disable(void *garbage) { - if (!vmm_coexistence) + if (!vmm_coexistence) { vmclear_local_vcpus(); - kvm_cpu_vmxoff(); + kvm_cpu_vmxoff(); + } write_cr4(read_cr4() & ~X86_CR4_VMXE); } @@ -3967,6 +3976,7 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) { int err; struct vcpu_vmx *vmx = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); + u64 phys_addr = __pa(per_cpu(vmxarea, smp_processor_id())); int cpu; if (!vmx) @@ -3990,9 +4000,11 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) if (vmm_coexistence) { preempt_disable(); + kvm_cpu_vmxon(phys_addr); vmcs_load(vmx->vmcs); err = vmx_vcpu_setup(vmx); vmcs_clear(vmx->vmcs); + kvm_cpu_vmxoff(); preempt_enable(); } else { vmcs_clear(vmx->vmcs); @@ -4138,12 +4150,16 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; struct vcpu_vmx *vmx = to_vmx(vcpu); + int cpu = raw_smp_processor_id(); + u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); u32 exec_control; vmx->rdtscp_enabled = false; if (vmx_rdtscp_supported()) { - if (vmm_coexistence) + if (vmm_coexistence) { + kvm_cpu_vmxon(phys_addr); vmcs_load(vmx->vmcs); + } exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); if (exec_control & SECONDARY_EXEC_RDTSCP) { best = kvm_find_cpuid_entry(vcpu, 0x80000001, 0); @@ -4155,8 +4171,10 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) exec_control); } } - if (vmm_coexistence) + if (vmm_coexistence) { vmcs_clear(vmx->vmcs); + kvm_cpu_vmxoff(); + } } }