diff mbox

KVM: Ensure the exit frequency to QEmu for coalesced MMIO

Message ID 1263976559-15480-1-git-send-email-sheng@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sheng Yang Jan. 20, 2010, 8:35 a.m. UTC
None
diff mbox

Patch

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;