From patchwork Wed Jan 20 08:35:59 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sheng Yang X-Patchwork-Id: 74016 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o0K8aXB1023587 for ; Wed, 20 Jan 2010 08:36:33 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751708Ab0ATIg3 (ORCPT ); Wed, 20 Jan 2010 03:36:29 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751721Ab0ATIg2 (ORCPT ); Wed, 20 Jan 2010 03:36:28 -0500 Received: from mga03.intel.com ([143.182.124.21]:13473 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751704Ab0ATIg2 (ORCPT ); Wed, 20 Jan 2010 03:36:28 -0500 Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga101.ch.intel.com with ESMTP; 20 Jan 2010 00:36:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.47,316,1257148800"; d="scan'208";a="234729104" Received: from syang10-desktop.sh.intel.com (HELO syang10-desktop) ([10.239.36.165]) by azsmga001.ch.intel.com with ESMTP; 20 Jan 2010 00:36:26 -0800 Received: from yasker by syang10-desktop with local (Exim 4.69) (envelope-from ) id 1NXW2j-00042A-44; Wed, 20 Jan 2010 16:36:01 +0800 From: Sheng Yang To: Marcelo Tosatti Cc: Avi Kivity , kvm@vger.kernel.org, Sheng Yang Subject: [PATCH] KVM: Ensure the exit frequency to QEmu for coalesced MMIO Date: Wed, 20 Jan 2010 16:35:59 +0800 Message-Id: <1263976559-15480-1-git-send-email-sheng@linux.intel.com> X-Mailer: git-send-email 1.6.3.3 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index a1f0b5d..eb8bb20 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -365,6 +365,8 @@ struct kvm_vcpu_arch { unsigned long singlestep_rip; /* fields used by HYPER-V emulation */ u64 hv_vapic; + + ktime_t latest_userspace_exit_time; }; struct kvm_mem_alias { diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 56a90a6..0b05f11 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4339,6 +4339,20 @@ out: return r; } +#ifdef CONFIG_KVM_MMIO + +#define KVM_USERSPACE_MMIO_MAX_INTERVAL (NSEC_PER_SEC / 25) +static bool mmio_need_exit_to_userspace(struct kvm_vcpu *vcpu) +{ + ktime_t gap, now = ktime_get(); + + gap = ktime_sub(now, vcpu->arch.latest_userspace_exit_time); + if (ktime_to_ns(gap) > KVM_USERSPACE_MMIO_MAX_INTERVAL) + return true; + + return false; +} +#endif static int __vcpu_run(struct kvm_vcpu *vcpu) { @@ -4404,6 +4418,10 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) kvm_resched(vcpu); vcpu->srcu_idx = srcu_read_lock(&kvm->srcu); } +#ifdef CONFIG_KVM_MMIO + if (mmio_need_exit_to_userspace(vcpu)) + r = 0; +#endif } srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx); @@ -4463,6 +4481,16 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) r = __vcpu_run(vcpu); +#ifdef CONFIG_KVM_MMIO + if (mmio_need_exit_to_userspace(vcpu)) { + /* Use KVM_EXIT_IRQ_WINDOW_OPEN because userspace would do + * nothing to handle it */ + kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; + r = 0; + } + vcpu->arch.latest_userspace_exit_time = ktime_get(); +#endif + out: if (vcpu->sigset_active) sigprocmask(SIG_SETMASK, &sigsaved, NULL); @@ -5455,6 +5483,9 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) goto fail_mmu_destroy; } vcpu->arch.mcg_cap = KVM_MAX_MCE_BANKS; +#ifdef CONFIG_KVM_MMIO + vcpu->arch.latest_userspace_exit_time = ktime_get(); +#endif return 0;