From patchwork Fri May 7 02:43:13 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Dongxiao" X-Patchwork-Id: 97563 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 o472i0Fp006548 for ; Fri, 7 May 2010 02:44:00 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752972Ab0EGCn6 (ORCPT ); Thu, 6 May 2010 22:43:58 -0400 Received: from mga01.intel.com ([192.55.52.88]:29925 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752380Ab0EGCn5 convert rfc822-to-8bit (ORCPT ); Thu, 6 May 2010 22:43:57 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 06 May 2010 19:41:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.52,345,1270450800"; d="scan'208";a="796220023" Received: from pgsmsx601.gar.corp.intel.com ([10.221.43.69]) by fmsmga001.fm.intel.com with ESMTP; 06 May 2010 19:43:45 -0700 Received: from shsmsx601.ccr.corp.intel.com (10.239.4.112) by pgsmsx601.gar.corp.intel.com (10.221.43.69) with Microsoft SMTP Server (TLS) id 8.2.176.0; Fri, 7 May 2010 10:43:10 +0800 Received: from shsmsx501.ccr.corp.intel.com ([10.239.4.141]) by shsmsx601.ccr.corp.intel.com ([10.239.4.112]) with mapi; Fri, 7 May 2010 10:43:09 +0800 From: "Xu, Dongxiao" To: "kvm@vger.kernel.org" CC: Avi Kivity , Marcelo Tosatti , Alexander Graf Date: Fri, 7 May 2010 10:43:13 +0800 Subject: [PATCH 4/4 v3] KVM: VMX: VMXON/VMXOFF usage changes. Thread-Topic: [PATCH 4/4 v3] KVM: VMX: VMXON/VMXOFF usage changes. Thread-Index: AcrtjwncAajvNgkVR1eKUtFhJe94zg== 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]); Fri, 07 May 2010 02:44:01 +0000 (UTC) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index c536b9d..59d7443 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -168,6 +168,8 @@ 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); @@ -786,8 +788,11 @@ 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_exclusive && vcpu->cpu != cpu) + if (!vmm_exclusive) + kvm_cpu_vmxon(phys_addr); + else if (vcpu->cpu != cpu) vcpu_clear(vmx); if (per_cpu(current_vmcs, cpu) != vmx->vmcs) { @@ -833,8 +838,10 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) static void vmx_vcpu_put(struct kvm_vcpu *vcpu) { __vmx_load_host_state(to_vmx(vcpu)); - if (!vmm_exclusive) + if (!vmm_exclusive) { __vcpu_clear(to_vmx(vcpu)); + kvm_cpu_vmxoff(); + } } static void vmx_fpu_activate(struct kvm_vcpu *vcpu) @@ -1257,9 +1264,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_exclusive) { + kvm_cpu_vmxon(phys_addr); + ept_sync_global(); + } return 0; } @@ -1285,8 +1294,10 @@ static void kvm_cpu_vmxoff(void) static void hardware_disable(void *garbage) { - vmclear_local_vcpus(); - kvm_cpu_vmxoff(); + if (vmm_exclusive) { + vmclear_local_vcpus(); + kvm_cpu_vmxoff(); + } write_cr4(read_cr4() & ~X86_CR4_VMXE); } @@ -3949,6 +3960,19 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu) kmem_cache_free(kvm_vcpu_cache, vmx); } +static inline void vmcs_init(struct vmcs *vmcs) +{ + u64 phys_addr = __pa(per_cpu(vmxarea, raw_smp_processor_id())); + + if (!vmm_exclusive) + kvm_cpu_vmxon(phys_addr); + + vmcs_clear(vmcs); + + if (!vmm_exclusive) + kvm_cpu_vmxoff(); +} + static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) { int err; @@ -3974,13 +3998,14 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) if (!vmx->vmcs) goto free_msrs; - vmcs_clear(vmx->vmcs); + vmcs_init(vmx->vmcs); cpu = get_cpu(); vmx_vcpu_load(&vmx->vcpu, cpu); err = vmx_vcpu_setup(vmx); vmx_vcpu_put(&vmx->vcpu); put_cpu(); + if (err) goto free_vmcs; if (vm_need_virtualize_apic_accesses(kvm)) @@ -4118,7 +4143,10 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) struct kvm_cpuid_entry2 *best; struct vcpu_vmx *vmx = to_vmx(vcpu); u32 exec_control; + int cpu; + cpu = get_cpu(); + vmx_vcpu_load(&vmx->vcpu, cpu); vmx->rdtscp_enabled = false; if (vmx_rdtscp_supported()) { exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); @@ -4133,6 +4161,9 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) } } } + vmx_vcpu_put(&vmx->vcpu); + put_cpu(); + } static void vmx_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)