public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] KVM: More 2.6.22 merge candidates
@ 2007-04-29 15:50 Avi Kivity
       [not found] ` <1177861822889-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Avi Kivity @ 2007-04-29 15:50 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA

The following patches, improving performance and the userspace interface,
will join the other pending kvm patches which I plan to send at the
end of the week.

 drivers/kvm/kvm.h      |    3 +-
 drivers/kvm/kvm_main.c |   35 +++++++++++------------
 drivers/kvm/kvm_svm.h  |   11 +++----
 drivers/kvm/mmu.c      |    2 +-
 drivers/kvm/svm.c      |   30 +++++++++++---------
 drivers/kvm/vmx.c      |   70 ++++++++++++++++++++++++++++++++++++++++-------
 include/linux/kvm.h    |    8 ++---
 7 files changed, 104 insertions(+), 55 deletions(-)

-------------------------------------------------------------------------
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/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/7] KVM: VMX: Properly shadow the CR0 register in the vcpu struct
       [not found] ` <1177861822889-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
@ 2007-04-29 15:50   ` Avi Kivity
  2007-04-29 15:50   ` [PATCH 2/7] KVM: VMX: Add lazy FPU support for VT Avi Kivity
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Avi Kivity @ 2007-04-29 15:50 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Anthony Liguori <aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>

Set all of the host mask bits for CR0 so that we can maintain a proper
shadow of CR0.  This exposes CR0.TS, paving the way for lazy fpu handling.

Signed-off-by: Anthony Liguori <aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
---
 drivers/kvm/kvm.h      |    2 +-
 drivers/kvm/kvm_main.c |    8 +++-----
 drivers/kvm/svm.c      |    4 ++--
 drivers/kvm/vmx.c      |   14 ++++++++------
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 61ff085..f99e89e 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -397,7 +397,7 @@ struct kvm_arch_ops {
 	void (*set_segment)(struct kvm_vcpu *vcpu,
 			    struct kvm_segment *var, int seg);
 	void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l);
-	void (*decache_cr0_cr4_guest_bits)(struct kvm_vcpu *vcpu);
+	void (*decache_cr4_guest_bits)(struct kvm_vcpu *vcpu);
 	void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0);
 	void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3);
 	void (*set_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4);
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 6755403..cdf0b17 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -510,7 +510,6 @@ EXPORT_SYMBOL_GPL(set_cr0);
 
 void lmsw(struct kvm_vcpu *vcpu, unsigned long msw)
 {
-	kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu);
 	set_cr0(vcpu, (vcpu->cr0 & ~0x0ful) | (msw & 0x0f));
 }
 EXPORT_SYMBOL_GPL(lmsw);
@@ -1117,7 +1116,6 @@ int emulate_clts(struct kvm_vcpu *vcpu)
 {
 	unsigned long cr0;
 
-	kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu);
 	cr0 = vcpu->cr0 & ~CR0_TS_MASK;
 	kvm_arch_ops->set_cr0(vcpu, cr0);
 	return X86EMUL_CONTINUE;
@@ -1318,7 +1316,7 @@ void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw,
 
 unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr)
 {
-	kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu);
+	kvm_arch_ops->decache_cr4_guest_bits(vcpu);
 	switch (cr) {
 	case 0:
 		return vcpu->cr0;
@@ -1934,7 +1932,7 @@ static int kvm_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
 	sregs->gdt.limit = dt.limit;
 	sregs->gdt.base = dt.base;
 
-	kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu);
+	kvm_arch_ops->decache_cr4_guest_bits(vcpu);
 	sregs->cr0 = vcpu->cr0;
 	sregs->cr2 = vcpu->cr2;
 	sregs->cr3 = vcpu->cr3;
@@ -1985,7 +1983,7 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 #endif
 	vcpu->apic_base = sregs->apic_base;
 
-	kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu);
+	kvm_arch_ops->decache_cr4_guest_bits(vcpu);
 
 	mmu_reset_needed |= vcpu->cr0 != sregs->cr0;
 	kvm_arch_ops->set_cr0(vcpu, sregs->cr0);
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 2a7a039..bddd023 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -738,7 +738,7 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
 	vcpu->svm->vmcb->save.gdtr.base = dt->base ;
 }
 
-static void svm_decache_cr0_cr4_guest_bits(struct kvm_vcpu *vcpu)
+static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
 {
 }
 
@@ -1759,7 +1759,7 @@ static struct kvm_arch_ops svm_arch_ops = {
 	.get_segment = svm_get_segment,
 	.set_segment = svm_set_segment,
 	.get_cs_db_l_bits = svm_get_cs_db_l_bits,
-	.decache_cr0_cr4_guest_bits = svm_decache_cr0_cr4_guest_bits,
+	.decache_cr4_guest_bits = svm_decache_cr4_guest_bits,
 	.set_cr0 = svm_set_cr0,
 	.set_cr3 = svm_set_cr3,
 	.set_cr4 = svm_set_cr4,
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index d28c848..0960811 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -810,11 +810,8 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
 
 #endif
 
-static void vmx_decache_cr0_cr4_guest_bits(struct kvm_vcpu *vcpu)
+static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
 {
-	vcpu->cr0 &= KVM_GUEST_CR0_MASK;
-	vcpu->cr0 |= vmcs_readl(GUEST_CR0) & ~KVM_GUEST_CR0_MASK;
-
 	vcpu->cr4 &= KVM_GUEST_CR4_MASK;
 	vcpu->cr4 |= vmcs_readl(GUEST_CR4) & ~KVM_GUEST_CR4_MASK;
 }
@@ -1205,7 +1202,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
 	vmcs_writel(TPR_THRESHOLD, 0);
 #endif
 
-	vmcs_writel(CR0_GUEST_HOST_MASK, KVM_GUEST_CR0_MASK);
+	vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL);
 	vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK);
 
 	vcpu->cr0 = 0x60000010;
@@ -1557,6 +1554,11 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 			return 1;
 		};
 		break;
+	case 2: /* clts */
+		vcpu_load_rsp_rip(vcpu);
+		set_cr0(vcpu, vcpu->cr0 & ~CR0_TS_MASK);
+		skip_emulated_instruction(vcpu);
+		return 1;
 	case 1: /*mov from cr*/
 		switch (cr) {
 		case 3:
@@ -2112,7 +2114,7 @@ static struct kvm_arch_ops vmx_arch_ops = {
 	.get_segment = vmx_get_segment,
 	.set_segment = vmx_set_segment,
 	.get_cs_db_l_bits = vmx_get_cs_db_l_bits,
-	.decache_cr0_cr4_guest_bits = vmx_decache_cr0_cr4_guest_bits,
+	.decache_cr4_guest_bits = vmx_decache_cr4_guest_bits,
 	.set_cr0 = vmx_set_cr0,
 	.set_cr3 = vmx_set_cr3,
 	.set_cr4 = vmx_set_cr4,
-- 
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/

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/7] KVM: VMX: Add lazy FPU support for VT
       [not found] ` <1177861822889-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
  2007-04-29 15:50   ` [PATCH 1/7] KVM: VMX: Properly shadow the CR0 register in the vcpu struct Avi Kivity
@ 2007-04-29 15:50   ` Avi Kivity
  2007-04-29 15:50   ` [PATCH 3/7] KVM: fix an if() condition Avi Kivity
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Avi Kivity @ 2007-04-29 15:50 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Anthony Liguori <aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>

Only save/restore the FPU host state when the guest is actually using the
FPU.

Signed-off-by: Anthony Liguori <aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
---
 drivers/kvm/vmx.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 0960811..1d2b41b 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -101,6 +101,13 @@ static inline int is_page_fault(u32 intr_info)
 		(INTR_TYPE_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK);
 }
 
+static inline int is_no_device(u32 intr_info)
+{
+	return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
+			     INTR_INFO_VALID_MASK)) ==
+		(INTR_TYPE_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK);
+}
+
 static inline int is_external_interrupt(u32 intr_info)
 {
 	return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK))
@@ -216,6 +223,16 @@ static void vmcs_write64(unsigned long field, u64 value)
 #endif
 }
 
+static void vmcs_clear_bits(unsigned long field, u32 mask)
+{
+	vmcs_writel(field, vmcs_readl(field) & ~mask);
+}
+
+static void vmcs_set_bits(unsigned long field, u32 mask)
+{
+	vmcs_writel(field, vmcs_readl(field) | mask);
+}
+
 /*
  * Switches to specified vcpu, until a matching vcpu_put(), but assumes
  * vcpu mutex is already taken.
@@ -833,6 +850,11 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 	}
 #endif
 
+	if (!(cr0 & CR0_TS_MASK)) {
+		vcpu->fpu_active = 1;
+		vmcs_clear_bits(EXCEPTION_BITMAP, CR0_TS_MASK);
+	}
+
 	vmcs_writel(CR0_READ_SHADOW, cr0);
 	vmcs_writel(GUEST_CR0,
 		    (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON);
@@ -842,6 +864,12 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 {
 	vmcs_writel(GUEST_CR3, cr3);
+
+	if (!(vcpu->cr0 & CR0_TS_MASK)) {
+		vcpu->fpu_active = 0;
+		vmcs_set_bits(GUEST_CR0, CR0_TS_MASK);
+		vmcs_set_bits(EXCEPTION_BITMAP, 1 << NM_VECTOR);
+	}
 }
 
 static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
@@ -1368,6 +1396,15 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 		asm ("int $2");
 		return 1;
 	}
+
+	if (is_no_device(intr_info)) {
+		vcpu->fpu_active = 1;
+		vmcs_clear_bits(EXCEPTION_BITMAP, 1 << NM_VECTOR);
+		if (!(vcpu->cr0 & CR0_TS_MASK))
+			vmcs_clear_bits(GUEST_CR0, CR0_TS_MASK);
+		return 1;
+	}
+
 	error_code = 0;
 	rip = vmcs_readl(GUEST_RIP);
 	if (intr_info & INTR_INFO_DELIEVER_CODE_MASK)
@@ -1556,7 +1593,11 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 		break;
 	case 2: /* clts */
 		vcpu_load_rsp_rip(vcpu);
-		set_cr0(vcpu, vcpu->cr0 & ~CR0_TS_MASK);
+		vcpu->fpu_active = 1;
+		vmcs_clear_bits(EXCEPTION_BITMAP, 1 << NM_VECTOR);
+		vmcs_clear_bits(GUEST_CR0, CR0_TS_MASK);
+		vcpu->cr0 &= ~CR0_TS_MASK;
+		vmcs_writel(CR0_READ_SHADOW, vcpu->cr0);
 		skip_emulated_instruction(vcpu);
 		return 1;
 	case 1: /*mov from cr*/
@@ -1806,8 +1847,10 @@ again:
 	if (vcpu->guest_debug.enabled)
 		kvm_guest_debug_pre(vcpu);
 
-	fx_save(vcpu->host_fx_image);
-	fx_restore(vcpu->guest_fx_image);
+	if (vcpu->fpu_active) {
+		fx_save(vcpu->host_fx_image);
+		fx_restore(vcpu->guest_fx_image);
+	}
 
 #ifdef CONFIG_X86_64
 	if (is_long_mode(vcpu)) {
@@ -1965,8 +2008,11 @@ again:
 	}
 #endif
 
-	fx_save(vcpu->guest_fx_image);
-	fx_restore(vcpu->host_fx_image);
+	if (vcpu->fpu_active) {
+		fx_save(vcpu->guest_fx_image);
+		fx_restore(vcpu->host_fx_image);
+	}
+
 	vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
 
 	asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
@@ -2078,6 +2124,7 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu)
 	vmcs_clear(vmcs);
 	vcpu->vmcs = vmcs;
 	vcpu->launched = 0;
+	vcpu->fpu_active = 1;
 
 	return 0;
 
-- 
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/

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/7] KVM: fix an if() condition
       [not found] ` <1177861822889-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
  2007-04-29 15:50   ` [PATCH 1/7] KVM: VMX: Properly shadow the CR0 register in the vcpu struct Avi Kivity
  2007-04-29 15:50   ` [PATCH 2/7] KVM: VMX: Add lazy FPU support for VT Avi Kivity
@ 2007-04-29 15:50   ` Avi Kivity
  2007-04-29 15:50   ` [PATCH 4/7] KVM: SVM: Only save/restore MSRs when needed Avi Kivity
                     ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Avi Kivity @ 2007-04-29 15:50 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Adrian Bunk

From: Adrian Bunk <bunk-HeJ8Db2Gnd6zQB+pC5nmwQ@public.gmane.org>

It might have worked in this case since PT_PRESENT_MASK is 1, but let's
express this correctly.

Signed-off-by: Adrian Bunk <bunk-HeJ8Db2Gnd6zQB+pC5nmwQ@public.gmane.org>
Signed-off-by: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
---
 drivers/kvm/mmu.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index 32c64f6..e8e2281 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -1408,7 +1408,7 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
 	for (i = 0; i < PT64_ENT_PER_PAGE; ++i, va += va_delta) {
 		u64 ent = pt[i];
 
-		if (!ent & PT_PRESENT_MASK)
+		if (!(ent & PT_PRESENT_MASK))
 			continue;
 
 		va = canonicalize(va);
-- 
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/

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/7] KVM: SVM: Only save/restore MSRs when needed
       [not found] ` <1177861822889-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
                     ` (2 preceding siblings ...)
  2007-04-29 15:50   ` [PATCH 3/7] KVM: fix an if() condition Avi Kivity
@ 2007-04-29 15:50   ` Avi Kivity
  2007-04-29 15:50   ` [PATCH 5/7] KVM: Remove extraneous guest entry on mmio read Avi Kivity
                     ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Avi Kivity @ 2007-04-29 15:50 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Signed-off-by-atKUWr5tajBWk0Htik3J/w,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Signed-off-by: Anthony Liguori <aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>

We only have to save/restore MSR_GS_BASE on every VMEXIT.  The rest can be
saved/restored when we leave the VCPU.  Since we don't emulate the DEBUGCTL
MSRs and the guest cannot write to them, we don't have to worry about
saving/restoring them at all.

This shaves a whopping 40% off raw vmexit costs on AMD.

Signed-off-by: Anthony Liguori <aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
---
 drivers/kvm/kvm_svm.h |   11 +++++------
 drivers/kvm/svm.c     |   26 +++++++++++++++-----------
 2 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/drivers/kvm/kvm_svm.h b/drivers/kvm/kvm_svm.h
index a1a9eba..a869983 100644
--- a/drivers/kvm/kvm_svm.h
+++ b/drivers/kvm/kvm_svm.h
@@ -9,17 +9,15 @@
 #include "svm.h"
 #include "kvm.h"
 
-static const u32 host_save_msrs[] = {
+static const u32 host_save_user_msrs[] = {
 #ifdef CONFIG_X86_64
 	MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE,
-	MSR_FS_BASE, MSR_GS_BASE,
+	MSR_FS_BASE,
 #endif
 	MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
-	MSR_IA32_DEBUGCTLMSR, /*MSR_IA32_LASTBRANCHFROMIP,
-	MSR_IA32_LASTBRANCHTOIP, MSR_IA32_LASTINTFROMIP,MSR_IA32_LASTINTTOIP,*/
 };
 
-#define NR_HOST_SAVE_MSRS ARRAY_SIZE(host_save_msrs)
+#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
 #define NUM_DB_REGS 4
 
 struct vcpu_svm {
@@ -32,7 +30,8 @@ struct vcpu_svm {
 
 	u64 next_rip;
 
-	u64 host_msrs[NR_HOST_SAVE_MSRS];
+	u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
+	u64 host_gs_base;
 	unsigned long host_cr2;
 	unsigned long host_db_regs[NUM_DB_REGS];
 	unsigned long host_dr6;
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index bddd023..9c15f32 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -522,8 +522,6 @@ static void init_vmcb(struct vmcb *vmcb)
 	control->msrpm_base_pa = msrpm_base;
 	control->tsc_offset = 0;
 	control->int_ctl = V_INTR_MASKING_MASK;
-	if (svm_has(SVM_FEATURE_LBRV))
-		control->lbr_ctl = 1ULL;
 
 	init_seg(&save->es);
 	init_seg(&save->ss);
@@ -611,7 +609,7 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu)
 
 static void svm_vcpu_load(struct kvm_vcpu *vcpu)
 {
-	int cpu;
+	int cpu, i;
 
 	cpu = get_cpu();
 	if (unlikely(cpu != vcpu->cpu)) {
@@ -626,10 +624,18 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu)
 		vcpu->svm->vmcb->control.tsc_offset += delta;
 		vcpu->cpu = cpu;
 	}
+
+	for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
+		rdmsrl(host_save_user_msrs[i], vcpu->svm->host_user_msrs[i]);
 }
 
 static void svm_vcpu_put(struct kvm_vcpu *vcpu)
 {
+	int i;
+
+	for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
+		wrmsrl(host_save_user_msrs[i], vcpu->svm->host_user_msrs[i]);
+
 	rdtscll(vcpu->host_tsc);
 	put_cpu();
 }
@@ -815,18 +821,16 @@ static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg)
 
 static void load_host_msrs(struct kvm_vcpu *vcpu)
 {
-	int i;
-
-	for ( i = 0; i < NR_HOST_SAVE_MSRS; i++)
-		wrmsrl(host_save_msrs[i], vcpu->svm->host_msrs[i]);
+#ifdef CONFIG_X86_64
+	wrmsrl(MSR_GS_BASE, vcpu->svm->host_gs_base);
+#endif
 }
 
 static void save_host_msrs(struct kvm_vcpu *vcpu)
 {
-	int i;
-
-	for ( i = 0; i < NR_HOST_SAVE_MSRS; i++)
-		rdmsrl(host_save_msrs[i], vcpu->svm->host_msrs[i]);
+#ifdef CONFIG_X86_64
+	rdmsrl(MSR_GS_BASE, vcpu->svm->host_gs_base);
+#endif
 }
 
 static void new_asid(struct kvm_vcpu *vcpu, struct svm_cpu_data *svm_data)
-- 
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/

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/7] KVM: Remove extraneous guest entry on mmio read
       [not found] ` <1177861822889-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
                     ` (3 preceding siblings ...)
  2007-04-29 15:50   ` [PATCH 4/7] KVM: SVM: Only save/restore MSRs when needed Avi Kivity
@ 2007-04-29 15:50   ` Avi Kivity
  2007-04-29 15:50   ` [PATCH 6/7] KVM: Don't require explicit indication of completion of mmio or pio Avi Kivity
  2007-04-29 15:50   ` [PATCH 7/7] KVM: Remove unused 'instruction_length' Avi Kivity
  6 siblings, 0 replies; 8+ messages in thread
From: Avi Kivity @ 2007-04-29 15:50 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA

When emulating an mmio read, we actually emulate twice: once to determine
the physical address of the mmio, and, after we've exited to userspace to
get the mmio value, we emulate again to place the value in the result
register and update any flags.

But we don't really need to enter the guest again for that, only to take
an immediate vmexit.  So, if we detect that we're doing an mmio read,
emulate a single instruction before entering the guest again.

Signed-off-by: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
---
 drivers/kvm/kvm.h      |    1 +
 drivers/kvm/kvm_main.c |    5 ++++-
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index f99e89e..41634fd 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -310,6 +310,7 @@ struct kvm_vcpu {
 	int mmio_size;
 	unsigned char mmio_data[8];
 	gpa_t mmio_phys_addr;
+	gva_t mmio_fault_cr2;
 	struct kvm_pio_request pio;
 	void *pio_data;
 
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index cdf0b17..a9ba42f 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1186,6 +1186,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
 	int r;
 	int cs_db, cs_l;
 
+	vcpu->mmio_fault_cr2 = cr2;
 	kvm_arch_ops->cache_regs(vcpu);
 
 	kvm_arch_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
@@ -1804,9 +1805,11 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 			r = complete_pio(vcpu);
 			if (r)
 				goto out;
-		} else {
+		} else if (!vcpu->mmio_is_write) {
 			memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
 			vcpu->mmio_read_completed = 1;
+			emulate_instruction(vcpu, kvm_run,
+					    vcpu->mmio_fault_cr2, 0);
 		}
 	}
 
-- 
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/

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/7] KVM: Don't require explicit indication of completion of mmio or pio
       [not found] ` <1177861822889-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
                     ` (4 preceding siblings ...)
  2007-04-29 15:50   ` [PATCH 5/7] KVM: Remove extraneous guest entry on mmio read Avi Kivity
@ 2007-04-29 15:50   ` Avi Kivity
  2007-04-29 15:50   ` [PATCH 7/7] KVM: Remove unused 'instruction_length' Avi Kivity
  6 siblings, 0 replies; 8+ messages in thread
From: Avi Kivity @ 2007-04-29 15:50 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA

It is illegal not to return from a pio or mmio request without completing
it, as mmio or pio is an atomic operation.  Therefore, we can simplify
the userspace interface by avoiding the completion indication.

Signed-off-by: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
---
 drivers/kvm/kvm_main.c |   28 +++++++++++++---------------
 include/linux/kvm.h    |    5 ++---
 2 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index a9ba42f..4c5b8db 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1237,8 +1237,10 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
 	kvm_arch_ops->decache_regs(vcpu);
 	kvm_arch_ops->set_rflags(vcpu, emulate_ctxt.eflags);
 
-	if (vcpu->mmio_is_write)
+	if (vcpu->mmio_is_write) {
+		vcpu->mmio_needed = 0;
 		return EMULATE_DO_MMIO;
+	}
 
 	return EMULATE_DONE;
 }
@@ -1692,8 +1694,6 @@ static int complete_pio(struct kvm_vcpu *vcpu)
 			vcpu->regs[VCPU_REGS_RSI] += delta;
 	}
 
-	vcpu->run->io_completed = 0;
-
 	kvm_arch_ops->decache_regs(vcpu);
 
 	io->count -= io->cur_count;
@@ -1800,20 +1800,18 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	/* re-sync apic's tpr */
 	vcpu->cr8 = kvm_run->cr8;
 
-	if (kvm_run->io_completed) {
-		if (vcpu->pio.cur_count) {
-			r = complete_pio(vcpu);
-			if (r)
-				goto out;
-		} else if (!vcpu->mmio_is_write) {
-			memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
-			vcpu->mmio_read_completed = 1;
-			emulate_instruction(vcpu, kvm_run,
-					    vcpu->mmio_fault_cr2, 0);
-		}
+	if (vcpu->pio.cur_count) {
+		r = complete_pio(vcpu);
+		if (r)
+			goto out;
 	}
 
-	vcpu->mmio_needed = 0;
+	if (vcpu->mmio_needed) {
+		memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
+		vcpu->mmio_read_completed = 1;
+		emulate_instruction(vcpu, kvm_run, vcpu->mmio_fault_cr2, 0);
+		vcpu->mmio_needed = 0;
+	}
 
 	if (kvm_run->exit_reason == KVM_EXIT_HYPERCALL) {
 		kvm_arch_ops->cache_regs(vcpu);
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 07bf353..738c2f5 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -11,7 +11,7 @@
 #include <asm/types.h>
 #include <linux/ioctl.h>
 
-#define KVM_API_VERSION 10
+#define KVM_API_VERSION 11
 
 /*
  * Architectural interrupt line count, and the size of the bitmap needed
@@ -58,9 +58,8 @@ enum kvm_exit_reason {
 /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */
 struct kvm_run {
 	/* in */
-	__u32 io_completed; /* mmio/pio request completed */
 	__u8 request_interrupt_window;
-	__u8 padding1[3];
+	__u8 padding1[7];
 
 	/* out */
 	__u32 exit_reason;
-- 
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/

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 7/7] KVM: Remove unused 'instruction_length'
       [not found] ` <1177861822889-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
                     ` (5 preceding siblings ...)
  2007-04-29 15:50   ` [PATCH 6/7] KVM: Don't require explicit indication of completion of mmio or pio Avi Kivity
@ 2007-04-29 15:50   ` Avi Kivity
  6 siblings, 0 replies; 8+ messages in thread
From: Avi Kivity @ 2007-04-29 15:50 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA

As we no longer emulate in userspace, this is meaningless.  We don't
compute it on SVM anyway.

Signed-off-by: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
---
 drivers/kvm/vmx.c   |    1 -
 include/linux/kvm.h |    5 ++---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 1d2b41b..74d058e 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1783,7 +1783,6 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 				exit_reason != EXIT_REASON_EXCEPTION_NMI )
 		printk(KERN_WARNING "%s: unexpected, valid vectoring info and "
 		       "exit reason is 0x%x\n", __FUNCTION__, exit_reason);
-	kvm_run->instruction_length = vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
 	if (exit_reason < kvm_vmx_max_exit_handlers
 	    && kvm_vmx_exit_handlers[exit_reason])
 		return kvm_vmx_exit_handlers[exit_reason](vcpu, kvm_run);
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 738c2f5..e6edca8 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -11,7 +11,7 @@
 #include <asm/types.h>
 #include <linux/ioctl.h>
 
-#define KVM_API_VERSION 11
+#define KVM_API_VERSION 12
 
 /*
  * Architectural interrupt line count, and the size of the bitmap needed
@@ -63,10 +63,9 @@ struct kvm_run {
 
 	/* out */
 	__u32 exit_reason;
-	__u32 instruction_length;
 	__u8 ready_for_interrupt_injection;
 	__u8 if_flag;
-	__u8 padding2[6];
+	__u8 padding2[2];
 
 	/* in (pre_kvm_run), out (post_kvm_run) */
 	__u64 cr8;
-- 
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/

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2007-04-29 15:50 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-29 15:50 [PATCH 0/7] KVM: More 2.6.22 merge candidates Avi Kivity
     [not found] ` <1177861822889-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-04-29 15:50   ` [PATCH 1/7] KVM: VMX: Properly shadow the CR0 register in the vcpu struct Avi Kivity
2007-04-29 15:50   ` [PATCH 2/7] KVM: VMX: Add lazy FPU support for VT Avi Kivity
2007-04-29 15:50   ` [PATCH 3/7] KVM: fix an if() condition Avi Kivity
2007-04-29 15:50   ` [PATCH 4/7] KVM: SVM: Only save/restore MSRs when needed Avi Kivity
2007-04-29 15:50   ` [PATCH 5/7] KVM: Remove extraneous guest entry on mmio read Avi Kivity
2007-04-29 15:50   ` [PATCH 6/7] KVM: Don't require explicit indication of completion of mmio or pio Avi Kivity
2007-04-29 15:50   ` [PATCH 7/7] KVM: Remove unused 'instruction_length' Avi Kivity

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox