From patchwork Thu Aug 27 01:20:02 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Tosatti X-Patchwork-Id: 44165 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n7R1VmSJ016572 for ; Thu, 27 Aug 2009 01:31:49 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754589AbZH0Bbo (ORCPT ); Wed, 26 Aug 2009 21:31:44 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754576AbZH0Bbn (ORCPT ); Wed, 26 Aug 2009 21:31:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36624 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754436AbZH0Bbk (ORCPT ); Wed, 26 Aug 2009 21:31:40 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n7R1VgxQ025163 for ; Wed, 26 Aug 2009 21:31:42 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n7R1Vg1g028090; Wed, 26 Aug 2009 21:31:42 -0400 Received: from amt.cnet (vpn-51-10.sfbay.redhat.com [10.14.51.10]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n7R1Vdqa024666; Wed, 26 Aug 2009 21:31:40 -0400 Received: from amt.cnet (amt.cnet [127.0.0.1]) by amt.cnet (Postfix) with ESMTP id CFAAF58815A; Wed, 26 Aug 2009 22:31:05 -0300 (BRT) Received: (from marcelo@localhost) by amt.cnet (8.14.3/8.14.3/Submit) id n7R1V4rE007010; Wed, 26 Aug 2009 22:31:04 -0300 Message-Id: <20090827012955.208915957@localhost.localdomain> References: <20090827012000.762063112@localhost.localdomain> User-Agent: quilt/0.46-1 Date: Wed, 26 Aug 2009 22:20:02 -0300 From: Marcelo Tosatti To: kvm@vger.kernel.org Cc: Marcelo Tosatti Subject: [patch 2/5] KVM: reintroduce guest mode bit and unify remote request code Content-Disposition: inline; filename=reintroduce-guest-mode X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Split KVM_REQ_KICKED in two bits: KVM_VCPU_KICKED, to indicate whether a vcpu has been IPI'ed, and KVM_VCPU_GUEST_MODE, in a separate vcpu_state variable. Unify remote requests with kvm_vcpu_kick. Synchronous requests wait on KVM_VCPU_GUEST_MODE, via wait_on_bit/wake_up_bit. Signed-off-by: Marcelo Tosatti Index: kvm/arch/x86/kvm/x86.c =================================================================== --- kvm.orig/arch/x86/kvm/x86.c +++ kvm/arch/x86/kvm/x86.c @@ -3586,11 +3586,14 @@ static int vcpu_enter_guest(struct kvm_v local_irq_disable(); - clear_bit(KVM_REQ_KICK, &vcpu->requests); - smp_mb__after_clear_bit(); + set_bit(KVM_VCPU_GUEST_MODE, &vcpu->vcpu_state); + barrier(); if (vcpu->requests || need_resched() || signal_pending(current)) { - set_bit(KVM_REQ_KICK, &vcpu->requests); + clear_bit(KVM_VCPU_KICKED, &vcpu->vcpu_state); + clear_bit(KVM_VCPU_GUEST_MODE, &vcpu->vcpu_state); + smp_mb__after_clear_bit(); + wake_up_bit(&vcpu->vcpu_state, KVM_VCPU_GUEST_MODE); local_irq_enable(); preempt_enable(); r = 1; @@ -3642,7 +3645,10 @@ static int vcpu_enter_guest(struct kvm_v set_debugreg(vcpu->arch.host_dr6, 6); set_debugreg(vcpu->arch.host_dr7, 7); - set_bit(KVM_REQ_KICK, &vcpu->requests); + clear_bit(KVM_VCPU_KICKED, &vcpu->vcpu_state); + clear_bit(KVM_VCPU_GUEST_MODE, &vcpu->vcpu_state); + smp_mb__after_clear_bit(); + wake_up_bit(&vcpu->vcpu_state, KVM_VCPU_GUEST_MODE); local_irq_enable(); ++vcpu->stat.exits; Index: kvm/include/linux/kvm_host.h =================================================================== --- kvm.orig/include/linux/kvm_host.h +++ kvm/include/linux/kvm_host.h @@ -42,6 +42,9 @@ #define KVM_USERSPACE_IRQ_SOURCE_ID 0 +#define KVM_VCPU_GUEST_MODE 0 +#define KVM_VCPU_KICKED 1 + struct kvm; struct kvm_vcpu; extern struct kmem_cache *kvm_vcpu_cache; @@ -83,6 +86,7 @@ struct kvm_vcpu { int cpu; struct kvm_run *run; unsigned long requests; + unsigned long vcpu_state; unsigned long guest_debug; int fpu_active; int guest_fpu_loaded; @@ -362,6 +366,7 @@ void kvm_arch_sync_events(struct kvm *kv int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu); void kvm_vcpu_kick(struct kvm_vcpu *vcpu); +void kvm_vcpu_ipi(struct kvm_vcpu *vcpu); int kvm_is_mmio_pfn(pfn_t pfn); Index: kvm/virt/kvm/kvm_main.c =================================================================== --- kvm.orig/virt/kvm/kvm_main.c +++ kvm/virt/kvm/kvm_main.c @@ -119,18 +119,26 @@ void vcpu_put(struct kvm_vcpu *vcpu) void kvm_vcpu_kick(struct kvm_vcpu *vcpu) { - int me; - int cpu = vcpu->cpu; - if (waitqueue_active(&vcpu->wq)) { wake_up_interruptible(&vcpu->wq); ++vcpu->stat.halt_wakeup; } + kvm_vcpu_ipi(vcpu); +} + +void kvm_vcpu_ipi(struct kvm_vcpu *vcpu) +{ + int me; + int cpu = vcpu->cpu; me = get_cpu(); - if (cpu != me && (unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) - if (!test_and_set_bit(KVM_REQ_KICK, &vcpu->requests)) - smp_send_reschedule(cpu); + if (cpu != me && (unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) { + if (test_bit(KVM_VCPU_GUEST_MODE, &vcpu->vcpu_state)) { + if (!test_and_set_bit(KVM_VCPU_KICKED, + &vcpu->vcpu_state)) + smp_send_reschedule(cpu); + } + } put_cpu(); } @@ -168,6 +176,30 @@ static bool make_all_cpus_request(struct return called; } +static int kvm_req_wait(void *unused) +{ + cpu_relax(); + return 0; +} + +static void kvm_vcpu_request(struct kvm_vcpu *vcpu, unsigned int req) +{ + set_bit(req, &vcpu->requests); + barrier(); + kvm_vcpu_ipi(vcpu); + wait_on_bit(&vcpu->vcpu_state, KVM_VCPU_GUEST_MODE, kvm_req_wait, + TASK_UNINTERRUPTIBLE); +} + +static void kvm_vcpus_request(struct kvm *kvm, unsigned int req) +{ + int i; + struct kvm_vcpu *vcpu; + + kvm_for_each_vcpu(i, vcpu, kvm) + kvm_vcpu_request(vcpu, req); +} + void kvm_flush_remote_tlbs(struct kvm *kvm) { if (make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH)) Index: kvm/arch/ia64/kvm/kvm-ia64.c =================================================================== --- kvm.orig/arch/ia64/kvm/kvm-ia64.c +++ kvm/arch/ia64/kvm/kvm-ia64.c @@ -655,12 +655,13 @@ again: host_ctx = kvm_get_host_context(vcpu); guest_ctx = kvm_get_guest_context(vcpu); - clear_bit(KVM_REQ_KICK, &vcpu->requests); - r = kvm_vcpu_pre_transition(vcpu); if (r < 0) goto vcpu_run_fail; + set_bit(KVM_VCPU_GUEST_MODE, &vcpu->vcpu_state); + barrier(); + up_read(&vcpu->kvm->slots_lock); kvm_guest_enter(); @@ -672,7 +673,10 @@ again: kvm_vcpu_post_transition(vcpu); vcpu->arch.launched = 1; - set_bit(KVM_REQ_KICK, &vcpu->requests); + clear_bit(KVM_VCPU_KICKED, &vcpu->vcpu_state); + clear_bit(KVM_VCPU_GUEST_MODE, &vcpu->vcpu_state); + smp_mb__after_clear_bit(); + wake_up_bit(&vcpu->vcpu_state, KVM_VCPU_GUEST_MODE); local_irq_enable(); /*