From patchwork Thu Mar 18 09:49:52 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Dongxiao" X-Patchwork-Id: 86657 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 o2I9ojQE004333 for ; Thu, 18 Mar 2010 09:50:45 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752199Ab0CRJun (ORCPT ); Thu, 18 Mar 2010 05:50:43 -0400 Received: from mga02.intel.com ([134.134.136.20]:61205 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751261Ab0CRJum convert rfc822-to-8bit (ORCPT ); Thu, 18 Mar 2010 05:50:42 -0400 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 18 Mar 2010 02:46:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.51,265,1267430400"; d="scan'208";a="501618052" Received: from pgsmsx602.gar.corp.intel.com ([10.221.43.81]) by orsmga002.jf.intel.com with ESMTP; 18 Mar 2010 02:49:51 -0700 Received: from shsmsx601.ccr.corp.intel.com (10.239.4.112) by pgsmsx602.gar.corp.intel.com (10.221.43.81) with Microsoft SMTP Server (TLS) id 8.2.176.0; Thu, 18 Mar 2010 17:49:45 +0800 Received: from shsmsx501.ccr.corp.intel.com ([10.239.4.141]) by shsmsx601.ccr.corp.intel.com ([10.239.4.112]) with mapi; Thu, 18 Mar 2010 17:49:45 +0800 From: "Xu, Dongxiao" To: "kvm@vger.kernel.org" CC: Avi Kivity , Marcelo Tosatti Date: Thu, 18 Mar 2010 17:49:52 +0800 Subject: [PATCH 2/3] KVM: VMX: VMCLEAR/VMPTRLD usage changes. Thread-Topic: [PATCH 2/3] KVM: VMX: VMCLEAR/VMPTRLD usage changes. Thread-Index: AcrGgFtkYkrVXianS5CDE4VsNV1H+Q== 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, 18 Mar 2010 09:50:45 +0000 (UTC) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 10e2c3c..aaf5b52 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -109,7 +109,6 @@ struct shared_msr_entry { struct vcpu_vmx { struct kvm_vcpu vcpu; - struct list_head local_vcpus_link; unsigned long host_rsp; int launched; u8 fail; @@ -164,8 +163,6 @@ static int init_rmode(struct kvm *kvm); static u64 construct_eptp(unsigned long root_hpa); static DEFINE_PER_CPU(struct vmcs *, vmxarea); -static DEFINE_PER_CPU(struct vmcs *, current_vmcs); -static DEFINE_PER_CPU(struct list_head, vcpus_on_cpu); static unsigned long *vmx_io_bitmap_a; static unsigned long *vmx_io_bitmap_b; @@ -455,28 +452,6 @@ static void vmcs_load(struct vmcs *vmcs) vmcs, phys_addr); } -static void __vcpu_clear(void *arg) -{ - struct vcpu_vmx *vmx = arg; - int cpu = raw_smp_processor_id(); - - if (vmx->vcpu.cpu == cpu) - vmcs_clear(vmx->vmcs); - if (per_cpu(current_vmcs, cpu) == vmx->vmcs) - per_cpu(current_vmcs, cpu) = NULL; - rdtscll(vmx->vcpu.arch.host_tsc); - list_del(&vmx->local_vcpus_link); - vmx->vcpu.cpu = -1; - vmx->launched = 0; -} - -static void vcpu_clear(struct vcpu_vmx *vmx) -{ - if (vmx->vcpu.cpu == -1) - return; - smp_call_function_single(vmx->vcpu.cpu, __vcpu_clear, vmx, 1); -} - static inline void vpid_sync_vcpu_all(struct vcpu_vmx *vmx) { if (vmx->vpid == 0) @@ -781,25 +756,15 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) struct vcpu_vmx *vmx = to_vmx(vcpu); u64 tsc_this, delta, new_offset; - if (vcpu->cpu != cpu) { - vcpu_clear(vmx); - kvm_migrate_timers(vcpu); - set_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests); - local_irq_disable(); - list_add(&vmx->local_vcpus_link, - &per_cpu(vcpus_on_cpu, cpu)); - local_irq_enable(); - } - - if (per_cpu(current_vmcs, cpu) != vmx->vmcs) { - per_cpu(current_vmcs, cpu) = vmx->vmcs; - vmcs_load(vmx->vmcs); - } + vmcs_load(vmx->vmcs); if (vcpu->cpu != cpu) { struct desc_ptr dt; unsigned long sysenter_esp; + kvm_migrate_timers(vcpu); + set_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests); + vcpu->cpu = cpu; /* * Linux uses per-cpu TSS and GDT, so set these when switching @@ -826,7 +791,11 @@ 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)); + struct vcpu_vmx *vmx = to_vmx(vcpu); + __vmx_load_host_state(vmx); + vmcs_clear(vmx->vmcs); + rdtscll(vmx->vcpu.arch.host_tsc); + vmx->launched = 0; } static void vmx_fpu_activate(struct kvm_vcpu *vcpu) @@ -1232,7 +1201,6 @@ static int hardware_enable(void *garbage) if (read_cr4() & X86_CR4_VMXE) return -EBUSY; - INIT_LIST_HEAD(&per_cpu(vcpus_on_cpu, cpu)); rdmsrl(MSR_IA32_FEATURE_CONTROL, old); if ((old & (FEATURE_CONTROL_LOCKED | FEATURE_CONTROL_VMXON_ENABLED)) @@ -1250,17 +1218,6 @@ static int hardware_enable(void *garbage) return 0; } -static void vmclear_local_vcpus(void) -{ - int cpu = raw_smp_processor_id(); - struct vcpu_vmx *vmx, *n; - - list_for_each_entry_safe(vmx, n, &per_cpu(vcpus_on_cpu, cpu), - local_vcpus_link) - __vcpu_clear(vmx); -} - - /* Just like cpu_vmxoff(), but with the __kvm_handle_fault_on_reboot() * tricks. */ @@ -1271,7 +1228,6 @@ static void kvm_cpu_vmxoff(void) static void hardware_disable(void *garbage) { - vmclear_local_vcpus(); kvm_cpu_vmxoff(); write_cr4(read_cr4() & ~X86_CR4_VMXE); } @@ -3951,7 +3907,6 @@ static void vmx_free_vmcs(struct kvm_vcpu *vcpu) struct vcpu_vmx *vmx = to_vmx(vcpu); if (vmx->vmcs) { - vcpu_clear(vmx); free_vmcs(vmx->vmcs); vmx->vmcs = NULL; } @@ -3975,7 +3930,6 @@ 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); - int cpu; if (!vmx) return ERR_PTR(-ENOMEM); @@ -3996,13 +3950,12 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) if (!vmx->vmcs) goto free_msrs; + preempt_disable(); + vmcs_load(vmx->vmcs); + err = vmx_vcpu_setup(vmx); vmcs_clear(vmx->vmcs); + preempt_enable(); - 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)) @@ -4142,6 +4095,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) vmx->rdtscp_enabled = false; if (vmx_rdtscp_supported()) { + 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); @@ -4153,6 +4107,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) exec_control); } } + vmcs_clear(vmx->vmcs); } }