public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: [PATCH 04/58] KVM: Avoid saving and restoring some host CPU state on lightweight vmexit
Date: Sun, 17 Jun 2007 12:43:45 +0300	[thread overview]
Message-ID: <11820734791893-git-send-email-avi@qumranet.com> (raw)
In-Reply-To: <1182073479890-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>

Many msrs and the like will only be used by the host if we schedule() or
return to userspace.  Therefore, we avoid saving them if we handle the
exit within the kernel, and if a reschedule is not requested.

Based on a patch from Eddie Dong <eddie.dong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> with a couple of
fixes by me.

Signed-off-by: Yaozu(Eddie) Dong <eddie.dong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Signed-off-by: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
---
 drivers/kvm/kvm.h      |    1 +
 drivers/kvm/kvm_main.c |    1 +
 drivers/kvm/vmx.c      |  105 +++++++++++++++++++++++++++--------------------
 3 files changed, 62 insertions(+), 45 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 152312c..7facebd 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -252,6 +252,7 @@ struct kvm_stat {
 	u32 halt_exits;
 	u32 request_irq_exits;
 	u32 irq_exits;
+	u32 light_exits;
 };
 
 struct kvm_vcpu {
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 8f1f07a..7d68258 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -72,6 +72,7 @@ static struct kvm_stats_debugfs_item {
 	{ "halt_exits", STAT_OFFSET(halt_exits) },
 	{ "request_irq", STAT_OFFSET(request_irq_exits) },
 	{ "irq_exits", STAT_OFFSET(irq_exits) },
+	{ "light_exits", STAT_OFFSET(light_exits) },
 	{ NULL }
 };
 
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 52bd5f0..84ce0c0 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -483,6 +483,13 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
 	case MSR_GS_BASE:
 		vmcs_writel(GUEST_GS_BASE, data);
 		break;
+	case MSR_LSTAR:
+	case MSR_SYSCALL_MASK:
+		msr = find_msr_entry(vcpu, msr_index);
+		if (msr)
+			msr->data = data;
+		load_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
+		break;
 #endif
 	case MSR_IA32_SYSENTER_CS:
 		vmcs_write32(GUEST_SYSENTER_CS, data);
@@ -1820,7 +1827,7 @@ static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	int fs_gs_ldt_reload_needed;
 	int r;
 
-again:
+preempted:
 	/*
 	 * Set host fs and gs selectors.  Unfortunately, 22.2.3 does not
 	 * allow segment selectors with cpl > 0 or ti == 1.
@@ -1851,13 +1858,6 @@ again:
 	if (vcpu->guest_debug.enabled)
 		kvm_guest_debug_pre(vcpu);
 
-	kvm_load_guest_fpu(vcpu);
-
-	/*
-	 * Loading guest fpu may have cleared host cr0.ts
-	 */
-	vmcs_writel(HOST_CR0, read_cr0());
-
 #ifdef CONFIG_X86_64
 	if (is_long_mode(vcpu)) {
 		save_msrs(vcpu->host_msrs + msr_offset_kernel_gs_base, 1);
@@ -1865,6 +1865,14 @@ again:
 	}
 #endif
 
+again:
+	kvm_load_guest_fpu(vcpu);
+
+	/*
+	 * Loading guest fpu may have cleared host cr0.ts
+	 */
+	vmcs_writel(HOST_CR0, read_cr0());
+
 	asm (
 		/* Store host registers */
 		"pushf \n\t"
@@ -1984,36 +1992,8 @@ again:
 		[cr2]"i"(offsetof(struct kvm_vcpu, cr2))
 	      : "cc", "memory" );
 
-	/*
-	 * Reload segment selectors ASAP. (it's needed for a functional
-	 * kernel: x86 relies on having __KERNEL_PDA in %fs and x86_64
-	 * relies on having 0 in %gs for the CPU PDA to work.)
-	 */
-	if (fs_gs_ldt_reload_needed) {
-		load_ldt(ldt_sel);
-		load_fs(fs_sel);
-		/*
-		 * If we have to reload gs, we must take care to
-		 * preserve our gs base.
-		 */
-		local_irq_disable();
-		load_gs(gs_sel);
-#ifdef CONFIG_X86_64
-		wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE));
-#endif
-		local_irq_enable();
-
-		reload_tss();
-	}
 	++vcpu->stat.exits;
 
-#ifdef CONFIG_X86_64
-	if (is_long_mode(vcpu)) {
-		save_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
-		load_msrs(vcpu->host_msrs, NR_BAD_MSRS);
-	}
-#endif
-
 	vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
 
 	asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
@@ -2035,24 +2015,59 @@ again:
 		if (r > 0) {
 			/* Give scheduler a change to reschedule. */
 			if (signal_pending(current)) {
-				++vcpu->stat.signal_exits;
-				post_kvm_run_save(vcpu, kvm_run);
+				r = -EINTR;
 				kvm_run->exit_reason = KVM_EXIT_INTR;
-				return -EINTR;
+				++vcpu->stat.signal_exits;
+				goto out;
 			}
 
 			if (dm_request_for_irq_injection(vcpu, kvm_run)) {
-				++vcpu->stat.request_irq_exits;
-				post_kvm_run_save(vcpu, kvm_run);
+				r = -EINTR;
 				kvm_run->exit_reason = KVM_EXIT_INTR;
-				return -EINTR;
+				++vcpu->stat.request_irq_exits;
+				goto out;
+			}
+			if (!need_resched()) {
+				++vcpu->stat.light_exits;
+				goto again;
 			}
-
-			kvm_resched(vcpu);
-			goto again;
 		}
 	}
 
+out:
+	/*
+	 * Reload segment selectors ASAP. (it's needed for a functional
+	 * kernel: x86 relies on having __KERNEL_PDA in %fs and x86_64
+	 * relies on having 0 in %gs for the CPU PDA to work.)
+	 */
+	if (fs_gs_ldt_reload_needed) {
+		load_ldt(ldt_sel);
+		load_fs(fs_sel);
+		/*
+		 * If we have to reload gs, we must take care to
+		 * preserve our gs base.
+		 */
+		local_irq_disable();
+		load_gs(gs_sel);
+#ifdef CONFIG_X86_64
+		wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE));
+#endif
+		local_irq_enable();
+
+		reload_tss();
+	}
+#ifdef CONFIG_X86_64
+	if (is_long_mode(vcpu)) {
+		save_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
+		load_msrs(vcpu->host_msrs, NR_BAD_MSRS);
+	}
+#endif
+
+	if (r > 0) {
+		kvm_resched(vcpu);
+		goto preempted;
+	}
+
 	post_kvm_run_save(vcpu, kvm_run);
 	return r;
 }
-- 
1.5.0.6


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

  parent reply	other threads:[~2007-06-17  9:43 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-17  9:43 [PATCH 00/58] KVM updates for 2.6.23 Avi Kivity
     [not found] ` <1182073479890-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-06-17  9:43   ` [PATCH 01/58] KVM: VMX: Enable io bitmaps to avoid IO port 0x80 VMEXITs Avi Kivity
2007-06-17  9:43   ` [PATCH 02/58] KVM: SVM: Allow direct guest access to PC debug port Avi Kivity
2007-06-17  9:43   ` [PATCH 03/58] KVM: Assume that writes smaller than 4 bytes are to non-pagetable pages Avi Kivity
2007-06-17  9:43   ` Avi Kivity [this message]
2007-06-17  9:43   ` [PATCH 05/58] KVM: Unindent some code Avi Kivity
2007-06-17  9:43   ` [PATCH 06/58] KVM: Reduce misfirings of the fork detector Avi Kivity
2007-06-17  9:43   ` [PATCH 07/58] KVM: Be more careful restoring fs on lightweight vmexit Avi Kivity
2007-06-17  9:43   ` [PATCH 08/58] KVM: Unify kvm_mmu_pre_write() and kvm_mmu_post_write() Avi Kivity
2007-06-17  9:43   ` [PATCH 09/58] KVM: MMU: Respect nonpae pagetable quadrant when zapping ptes Avi Kivity
2007-06-17  9:43   ` [PATCH 10/58] KVM: Update shadow pte on write to guest pte Avi Kivity
2007-06-17  9:43   ` [PATCH 11/58] KVM: Increase mmu shadow cache to 1024 pages Avi Kivity
2007-06-17  9:43   ` [PATCH 12/58] KVM: Fix potential guest state leak into host Avi Kivity
2007-06-17  9:43   ` [PATCH 13/58] KVM: Move some more msr mangling into vmx_save_host_state() Avi Kivity
2007-06-17  9:43   ` [PATCH 14/58] KVM: Rationalize exception bitmap usage Avi Kivity
2007-06-17  9:43   ` [PATCH 15/58] KVM: Consolidate guest fpu activation and deactivation Avi Kivity
2007-06-17  9:43   ` [PATCH 16/58] KVM: Set cr0.mp for guests Avi Kivity
2007-06-17  9:43   ` [PATCH 17/58] KVM: Implement IA32_EBL_CR_POWERON msr Avi Kivity
2007-06-17  9:43   ` [PATCH 18/58] KVM: MMU: Simplify kvm_mmu_free_page() a tiny bit Avi Kivity
2007-06-17  9:44   ` [PATCH 19/58] KVM: MMU: Store shadow page tables as kernel virtual addresses, not physical Avi Kivity
2007-06-17  9:44   ` [PATCH 20/58] KVM: VMX: Only reload guest msrs if they are already loaded Avi Kivity
2007-06-17  9:44   ` [PATCH 21/58] KVM: Avoid corrupting tr in real mode Avi Kivity
2007-06-17  9:44   ` [PATCH 22/58] KVM: Fix vmx I/O bitmap initialization on highmem systems Avi Kivity
2007-06-17  9:44   ` [PATCH 23/58] KVM: VMX: Use local labels in inline assembly Avi Kivity
2007-06-17  9:44   ` [PATCH 24/58] KVM: VMX: Handle #SS faults from real mode Avi Kivity
2007-06-17  9:44   ` [PATCH 25/58] KVM: VMX: Avoid saving and restoring msrs on lightweight vmexit Avi Kivity
2007-06-17  9:44   ` [PATCH 26/58] KVM: VMX: Cleanup redundant code in MSR set Avi Kivity
2007-06-17  9:44   ` [PATCH 27/58] KVM: VMX: Avoid saving and restoring msr_efer on lightweight vmexit Avi Kivity
2007-06-17  9:44   ` [PATCH 28/58] Use menuconfig objects II - KVM/Virt Avi Kivity
2007-06-17  9:44   ` [PATCH 29/58] KVM: x86 emulator: implement wbinvd Avi Kivity
2007-06-17  9:44   ` [PATCH 30/58] KVM: Fix includes Avi Kivity
2007-06-17  9:44   ` [PATCH 31/58] KVM: Use symbolic constants instead of magic numbers Avi Kivity
2007-06-17  9:44   ` [PATCH 32/58] KVM: MMU: Use slab caches for shadow pages and their headers Avi Kivity
2007-06-17  9:44   ` [PATCH 33/58] KVM: MMU: Simplify fetch() a little bit Avi Kivity
2007-06-17  9:44   ` [PATCH 34/58] KVM: MMU: Move set_pte_common() to pte width dependent code Avi Kivity
2007-06-17  9:44   ` [PATCH 35/58] KVM: MMU: Pass the guest pde to set_pte_common Avi Kivity
2007-06-17  9:44   ` [PATCH 36/58] KVM: MMU: Fold fix_read_pf() into set_pte_common() Avi Kivity
2007-06-17  9:44   ` [PATCH 37/58] KVM: MMU: Fold fix_write_pf() " Avi Kivity
2007-06-17  9:44   ` [PATCH 38/58] KVM: Move shadow pte modifications from set_pte/set_pde to set_pde_common() Avi Kivity
2007-06-17  9:44   ` [PATCH 39/58] KVM: Make shadow pte updates atomic Avi Kivity
2007-06-17  9:44   ` [PATCH 40/58] KVM: MMU: Make setting shadow ptes atomic on i386 Avi Kivity
2007-06-17  9:44   ` [PATCH 41/58] KVM: MMU: Remove cr0.wp tricks Avi Kivity
2007-06-17  9:44   ` [PATCH 42/58] KVM: MMU: Simpify accessed/dirty/present/nx bit handling Avi Kivity
2007-06-17  9:44   ` [PATCH 43/58] KVM: MMU: Don't cache guest access bits in the shadow page table Avi Kivity
2007-06-17  9:44   ` [PATCH 44/58] KVM: MMU: Remove unused large page marker Avi Kivity
2007-06-17  9:44   ` [PATCH 45/58] KVM: Lazy guest cr3 switching Avi Kivity
2007-06-17  9:44   ` [PATCH 46/58] KVM: Replace C code with call to ARRAY_SIZE() macro Avi Kivity
2007-06-17  9:44   ` [PATCH 47/58] KVM: Remove unnecessary initialization and checks in mark_page_dirty() Avi Kivity
2007-06-17  9:44   ` [PATCH 48/58] KVM: Fix vcpu freeing for guest smp Avi Kivity
2007-06-17  9:44   ` [PATCH 49/58] KVM: Fix adding an smp virtual machine to the vm list Avi Kivity
2007-06-17  9:44   ` [PATCH 50/58] KVM: Enable guest smp Avi Kivity
2007-06-17  9:44   ` [PATCH 51/58] KVM: Move duplicate halt handling code into kvm_main.c Avi Kivity
2007-06-17  9:44   ` [PATCH 52/58] KVM: Emulate hlt on real mode for Intel Avi Kivity
2007-06-17  9:44   ` [PATCH 53/58] KVM: Keep an upper bound of initialized vcpus Avi Kivity
2007-06-17  9:44   ` [PATCH 54/58] KVM: Flush remote tlbs when reducing shadow pte permissions Avi Kivity
2007-06-17  9:44   ` [PATCH 55/58] KVM: SVM: Replace memset(<addr>, 0, PAGESIZE) with clear_page(<addr>) Avi Kivity
2007-06-17  9:44   ` [PATCH 56/58] KVM: VMX: " Avi Kivity
2007-06-17  9:44   ` [PATCH 57/58] KVM: Initialize the BSP bit in the APIC_BASE msr correctly Avi Kivity
2007-06-17  9:44   ` [PATCH 58/58] KVM: VMX: Ensure vcpu time stamp counter is monotonous Avi Kivity

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11820734791893-git-send-email-avi@qumranet.com \
    --to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
    --cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox