Skip to contentSkip to conversation

Lazy FPU for SVM

PATCH Applied Anthony Liguori 5 participants 17 messages Apr 23, 2007 – Apr 25, 2007 12 messages not in the archive KVM

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Lazy FPU for SVM

Attached patch implements lazy FPU save/restore for SVM. It's much more conservative than my previous patch. We can now mark the guest FPU as inactive whenever we want which will trigger CR0.TS to be set in the guest's shadowed CR0.

Right now, we only mark the FPU as inactive when the guest does (via a mov %cr0, clts, etc.) or during a mov %cr3. There may be a better heuristic out there but this seemed like the obvious one.

I'm still playing around with the VT version of this patch so I'll post that tomorrow.

I've tested on a 32bit and 64bit SVM host using Avi's previously posted fpu-test and some others. Everything seems to be fine.

Regards,

Anthony Liguori

Author: Anthony Liguori <aliguori-r/[email protected]>
Date:   Sun Apr 22 20:34:03 2007 -0500

Lazy FPU support for SVM.

drivers/kvm/kvm.h +4 -0
index d1a90c5..4859c32 100644
@@ -63,6 +63,9 @@
 #define FX_BUF_SIZE (2 * FX_IMAGE_SIZE + FX_IMAGE_ALIGN)
 
 #define DE_VECTOR 0
+#define DB_VECTOR 2
+#define UD_VECTOR 6
+#define NM_VECTOR 7
 #define DF_VECTOR 8
 #define TS_VECTOR 10
 #define NP_VECTOR 11
@@ -301,6 +304,7 @@ struct kvm_vcpu {
 	char fx_buf[FX_BUF_SIZE];
 	char *host_fx_image;
 	char *guest_fx_image;
+	int fpu_active;
 
 	int mmio_needed;
 	int mmio_read_completed;
drivers/kvm/svm.c +35 -8

91 lines not on this page · raw message

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

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

A message that is not in the archive (sent off-list or not yet received): 462C2048.4040700-r/[email protected]

#2 lore raw
Quoted 32 lines · Anthony Liguori

Attached patch implements lazy FPU save/restore for SVM. It's much more conservative than my previous patch. We can now mark the guest FPU as inactive whenever we want which will trigger CR0.TS to be set in the guest's shadowed CR0.

Right now, we only mark the FPU as inactive when the guest does (via a mov %cr0, clts, etc.) or during a mov %cr3. There may be a better heuristic out there but this seemed like the obvious one.

I'm still playing around with the VT version of this patch so I'll post that tomorrow.

I've tested on a 32bit and 64bit SVM host using Avi's previously posted fpu-test and some others. Everything seems to be fine.

Regards,

Anthony Liguori
------------------------------------------------------------------------

Author: Anthony Liguori <aliguori-r/[email protected]>
Date:   Sun Apr 22 20:34:03 2007 -0500

Lazy FPU support for SVM.

drivers/kvm/kvm.h +0 -0
index d1a90c5..4859c32 100644

drivers/kvm/kvm.h line 69

Quoted 7 lines
drivers/kvm/kvm.h +3 -0
@@ -63,6 +63,9 @@
 #define FX_BUF_SIZE (2 * FX_IMAGE_SIZE + FX_IMAGE_ALIGN)
 
 #define DE_VECTOR 0
+#define DB_VECTOR 2
+#define UD_VECTOR 6
+#define NM_VECTOR 7
 

This, while a nice cleanup, is unrelated.

Quoted 47 lines
drivers/kvm/kvm.h +0 -0
 #define DF_VECTOR 8
 #define TS_VECTOR 10

#define NP_VECTOR 11

drivers/kvm/kvm.h +1 -0
@@ -301,6 +304,7 @@ struct kvm_vcpu {
 	char fx_buf[FX_BUF_SIZE];
 	char *host_fx_image;
 	char *guest_fx_image;
+	int fpu_active;
 
 	int mmio_needed;
 	int mmio_read_completed;
drivers/kvm/svm.c +6 -4
index 644efc5..bbde031 100644
@@ -30,10 +30,6 @@ MODULE_LICENSE("GPL");
 #define IOPM_ALLOC_ORDER 2
 #define MSRPM_ALLOC_ORDER 1
 
-#define DB_VECTOR 1
-#define UD_VECTOR 6
-#define GP_VECTOR 13
-
 #define DR7_GD_MASK (1 << 13)
 #define DR6_BD_MASK (1 << 13)
 #define CR4_DE_MASK (1UL << 3)
@@ -587,6 +583,7 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu)
 	init_vmcb(vcpu->svm->vmcb);
 
 	fx_init(vcpu);
+	vcpu->fpu_active = 1;
 	vcpu->apic_base = 0xfee00000 |
 			/*for vcpu 0*/ MSR_IA32_APICBASE_BSP |
 			MSR_IA32_APICBASE_ENABLE;
@@ -756,6 +753,11 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 		}
 	}
 #endif
+	if ((vcpu->cr0 & CR0_TS_MASK) && !(cr0 & CR0_TS_MASK)) {
+		vcpu->svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
+		vcpu->fpu_active = 1;
+	}
+ 
 	vcpu->cr0 = cr0;
 	cr0 |= CR0_PG_MASK | CR0_WP_MASK;
 	cr0 &= ~(CR0_CD_MASK | CR0_NW_MASK);

drivers/kvm/svm.c static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) · line 936

Quoted 7 lines
drivers/kvm/svm.c +3 -0
@@ -928,6 +930,20 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	return 0;
 }
 
+static int nm_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       spin_lock(&vcpu->kvm->lock);
 

Why is the lock needed? everything below is vcpu-local AFAICS.

Quoted 52 lines
drivers/kvm/svm.c +11 -0
+
+       vcpu->svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
+       if (!(vcpu->cr0 & CR0_TS_MASK))
+               vcpu->svm->vmcb->save.cr0 &= ~CR0_TS_MASK;
+       vcpu->fpu_active = 1;
+
+       spin_unlock(&vcpu->kvm->lock);
+
+       return 1;
+}
+
 static int shutdown_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
drivers/kvm/svm.c +9 -4
 	/*
@@ -1292,6 +1308,7 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu,
 	[SVM_EXIT_WRITE_DR5]			= emulate_on_interception,
 	[SVM_EXIT_WRITE_DR7]			= emulate_on_interception,
 	[SVM_EXIT_EXCP_BASE + PF_VECTOR] 	= pf_interception,
+	[SVM_EXIT_EXCP_BASE + NM_VECTOR] 	= nm_interception,
 	[SVM_EXIT_INTR] 			= nop_on_interception,
 	[SVM_EXIT_NMI]				= nop_on_interception,
 	[SVM_EXIT_SMI]				= nop_on_interception,
@@ -1481,8 +1498,10 @@ again:
 		load_db_regs(vcpu->svm->db_regs);
 	}
 
-	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);
+	}
 
 	asm volatile (
 #ifdef CONFIG_X86_64
@@ -1593,8 +1612,10 @@ again:
 #endif
 		: "cc", "memory" );
 
-	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);
+	}
 
 	if ((vcpu->svm->vmcb->save.dr7 & 0xff))
 		load_db_regs(vcpu->svm->host_db_regs);
@@ -1664,6 +1685,12 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
 {
 	vcpu->svm->vmcb->save.cr3 = root;

drivers/kvm/svm.c static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root) · line 1696

Quoted 10 lines
drivers/kvm/svm.c +6 -0
 	force_new_asid(vcpu);
+ 
+	if (vcpu->fpu_active) {
+		vcpu->svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
+		vcpu->svm->vmcb->save.cr0 |= CR0_TS_MASK;
+		vcpu->fpu_active = 0;
+	}
 }
 
 static void svm_inject_page_fault(struct kvm_vcpu *vcpu,

Any numbers? I use user/test/vmexit.c to test as it gives the highest relative speedup.

Signature · 8 lines
error compiling committee.c: too many arguments to function


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

A message that is not in the archive (sent off-list or not yet received): 462C574E.2030304-atKUWr5tajBWk0Htik3J/[email protected]

#4 lore raw
Quoted 14 lines · Avi Kivity
Quoted 13 lines · Anthony Liguori
Author: Anthony Liguori <aliguori-r/[email protected]>
Date:   Sun Apr 22 20:34:03 2007 -0500

Lazy FPU support for SVM.

drivers/kvm/kvm.h +0 -0
index d1a90c5..4859c32 100644
@@ -63,6 +63,9 @@
 #define FX_BUF_SIZE (2 * FX_IMAGE_SIZE + FX_IMAGE_ALIGN)
 
Quoted 7 lines

drivers/kvm/kvm.h line 69

Quoted 5 lines
drivers/kvm/kvm.h +3 -0
 #define DE_VECTOR 0
+#define DB_VECTOR 2
+#define UD_VECTOR 6
+#define NM_VECTOR 7
 

This, while a nice cleanup, is unrelated.

I had to add the NM_VECTOR so I moved the others too. Attached is a patch that doesn't move those. I noticed that the #define's in general need some love. There's quite a lot in kvm.h that's specific to vmx and there's a bit of asymmetry between vmx and svm (svm has kvm_svm.h, vmx used to but it was removed recently). There's also a ton of unused #define's (quite a few that are typos).

I was planning on submitting a cleanup patch series today so I'll just fold the above changes into that.

Quoted 8 lines

drivers/kvm/kvm.h

Quoted 6 lines
drivers/kvm/kvm.h +3 -0
+static int nm_interception(struct kvm_vcpu *vcpu, struct kvm_run 
 *kvm_run)
+{
+       spin_lock(&vcpu->kvm->lock);

Why is the lock needed? everything below is vcpu-local AFAICS.

You're right, removed in attached patch.

Quoted 13 lines
Quoted 13 lines
drivers/kvm/kvm.h +5 -0
@@ -1664,6 +1685,12 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, 
 unsigned long root)
 {
     vcpu->svm->vmcb->save.cr3 = root;
     force_new_asid(vcpu);
+ +    if (vcpu->fpu_active) {
+        vcpu->svm->vmcb->control.intercept_exceptions |= (1 << 
 NM_VECTOR);
+        vcpu->svm->vmcb->save.cr0 |= CR0_TS_MASK;
+        vcpu->fpu_active = 0;
+    }
 }
Quoted 4 lines
Quoted 2 lines

static void svm_inject_page_fault(struct kvm_vcpu *vcpu,

Any numbers? I use user/test/vmexit.c to test as it gives the highest relative speedup.

Hard to say exactly because of the noise. I did two runs of 4 test/vmexit:

Before 4091, 4194, 4559, 4439
After: 3979, 4324, 3918, 3910

So there's definitely a speedup, but probably only 100-200 cycles.

Regards,

Anthony Liguori

Author: Anthony Liguori <aliguori-r/[email protected]>
Date:   Mon Apr 23 09:17:21 2007 -0500

Lazy FPU support for SVM.

drivers/kvm/kvm.h +2 -0
index d1a90c5..61ff085 100644
@@ -63,6 +63,7 @@
 #define FX_BUF_SIZE (2 * FX_IMAGE_SIZE + FX_IMAGE_ALIGN)
 
 #define DE_VECTOR 0
+#define NM_VECTOR 7
 #define DF_VECTOR 8
 #define TS_VECTOR 10
 #define NP_VECTOR 11
@@ -301,6 +302,7 @@ struct kvm_vcpu {
 	char fx_buf[FX_BUF_SIZE];
 	char *host_fx_image;
 	char *guest_fx_image;
+	int fpu_active;
 
 	int mmio_needed;
 	int mmio_read_completed;
drivers/kvm/svm.c +31 -4
index 644efc5..9438931 100644
@@ -587,6 +587,7 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu)
 	init_vmcb(vcpu->svm->vmcb);
 
 	fx_init(vcpu);
+	vcpu->fpu_active = 1;
 	vcpu->apic_base = 0xfee00000 |
 			/*for vcpu 0*/ MSR_IA32_APICBASE_BSP |
 			MSR_IA32_APICBASE_ENABLE;
@@ -756,6 +757,11 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 		}
 	}
 #endif
+	if ((vcpu->cr0 & CR0_TS_MASK) && !(cr0 & CR0_TS_MASK)) {
+		vcpu->svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
+		vcpu->fpu_active = 1;
+	}
+ 
 	vcpu->cr0 = cr0;
 	cr0 |= CR0_PG_MASK | CR0_WP_MASK;
 	cr0 &= ~(CR0_CD_MASK | CR0_NW_MASK);
@@ -928,6 +934,16 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	return 0;
 }
 
+static int nm_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       vcpu->svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
+       if (!(vcpu->cr0 & CR0_TS_MASK))
+               vcpu->svm->vmcb->save.cr0 &= ~CR0_TS_MASK;
+       vcpu->fpu_active = 1;
+
+       return 1;
+}
+
 static int shutdown_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	/*
@@ -1292,6 +1308,7 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu,
 	[SVM_EXIT_WRITE_DR5]			= emulate_on_interception,
 	[SVM_EXIT_WRITE_DR7]			= emulate_on_interception,
 	[SVM_EXIT_EXCP_BASE + PF_VECTOR] 	= pf_interception,
+	[SVM_EXIT_EXCP_BASE + NM_VECTOR] 	= nm_interception,
 	[SVM_EXIT_INTR] 			= nop_on_interception,
 	[SVM_EXIT_NMI]				= nop_on_interception,
 	[SVM_EXIT_SMI]				= nop_on_interception,
@@ -1481,8 +1498,10 @@ again:
 		load_db_regs(vcpu->svm->db_regs);
 	}
 
-	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);
+	}
 
 	asm volatile (
 #ifdef CONFIG_X86_64
@@ -1593,8 +1612,10 @@ again:
 #endif
 		: "cc", "memory" );
 
-	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);
+	}
 
 	if ((vcpu->svm->vmcb->save.dr7 & 0xff))
 		load_db_regs(vcpu->svm->host_db_regs);
@@ -1664,6 +1685,12 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
 {
 	vcpu->svm->vmcb->save.cr3 = root;
 	force_new_asid(vcpu);
+ 
+	if (vcpu->fpu_active) {
+		vcpu->svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
+		vcpu->svm->vmcb->save.cr0 |= CR0_TS_MASK;
+		vcpu->fpu_active = 0;
+	}
 }
 
 static void svm_inject_page_fault(struct kvm_vcpu *vcpu,

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

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

A message that is not in the archive (sent off-list or not yet received): [email protected]

Applied
#6 lore raw

Anthony Liguori wrote:

[updated patch]

Applied.

Quoted 9 lines

Hard to say exactly because of the noise. I did two runs of 4 test/vmexit:

Before 4091, 4194, 4559, 4439
After: 3979, 4324, 3918, 3910

So there's definitely a speedup, but probably only 100-200 cycles.

Running on an idle, headless server with the vcpu pinned reduces variability to a few cycles in the after case. Strangely, the variability is high in the before case. I get a similar disappointing result of 100-200 cycles.

Signature · 8 lines
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


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

A message that is not in the archive (sent off-list or not yet received): 462DDE52.5040303-atKUWr5tajBWk0Htik3J/[email protected]

#8 lore raw
Quoted 13 lines · Avi Kivity

Anthony Liguori wrote:

[updated patch]

Applied.

Quoted 6 lines

Hard to say exactly because of the noise. I did two runs of 4 test/vmexit:

Before 4091, 4194, 4559, 4439
After: 3979, 4324, 3918, 3910

Quoted 9 lines
Quoted 3 lines

So there's definitely a speedup, but probably only 100-200 cycles.

Running on an idle, headless server with the vcpu pinned reduces variability to a few cycles in the after case. Strangely, the variability is high in the before case. I get a similar disappointing result of 100-200 cycles.

I previously measured how long fx_save/fx_restore took and it was right around 150 cycles on AMD.

Regards,

Anthony Liguori

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

A message that is not in the archive (sent off-list or not yet received): [email protected]

#10 lore raw
Quoted 18 lines · Anthony Liguori
Quoted 17 lines · Avi Kivity

Anthony Liguori wrote:

[updated patch]

Applied.

Quoted 9 lines

Hard to say exactly because of the noise. I did two runs of 4 test/vmexit:

Before 4091, 4194, 4559, 4439
After: 3979, 4324, 3918, 3910

So there's definitely a speedup, but probably only 100-200 cycles.

Quoted 8 lines
Quoted 5 lines

Running on an idle, headless server with the vcpu pinned reduces variability to a few cycles in the after case. Strangely, the variability is high in the before case. I get a similar disappointing result of 100-200 cycles.

I previously measured how long fx_save/fx_restore took and it was right around 150 cycles on AMD.

Well, we're calling it twice per vmexit.

A save/restore pair is 313 cycles on a Woodcrest; two of those make 626 out of ~4000 cycles should get us a nice 15% gain.

Signature · 8 lines
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
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/
#11 lore raw

PATCH 1/1 Remove redundant MSR save/restore

In reply to a message not in the archive

This patch is to remove the redundant MSR save/restore at lightweight VM EXIT time. With this patch VMX guest KB performance can increase 17-37%. (I only tested it on KVM-18 since the git tree still has problem in my side, but I'd like to post this earlier to collect more feedback) Thanks, eddie

commit 11554c848e14f5322210c640e4a7ddeabe961282

Author: Yaozu Dong <[email protected]>
Date:   Wed Apr 25 14:14:17 2007 +0800

Avoid MSR save/restore for lightweight VM EXIT where no task switch nor qemu user mode is entered.

drivers/kvm/kvm_vmx.h +1 -9
index d139f73..f1bf7ad 100644
@@ -1,14 +1,6 @@
 #ifndef __KVM_VMX_H
 #define __KVM_VMX_H
 
-#ifdef CONFIG_X86_64
-/*
- * avoid save/load MSR_SYSCALL_MASK and MSR_LSTAR by std vt
- * mechanism (cpu bug AA24)
- */
-#define NR_BAD_MSRS 2
-#else
-#define NR_BAD_MSRS 0
-#endif
+#define NR_HW_SAVE_MSRS  1
 
 #endif
drivers/kvm/vmx.c +21 -19
index fbbf9d6..3d2176f 100644
@@ -71,10 +71,11 @@ static struct kvm_vmx_segment_field {
 };
 
 static const u32 vmx_msr_index[] = {
+	MSR_K6_STAR,
 #ifdef CONFIG_X86_64
 	MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR, MSR_KERNEL_GS_BASE,
 #endif
-	MSR_EFER, MSR_K6_STAR,
+	MSR_EFER,
 };
 #define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index)
 
@@ -991,7 +992,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
 	struct descriptor_table dt;
 	int i;
 	int ret = 0;
-	int nr_good_msrs;
+	int nr_sw_save_msrs;
 	extern asmlinkage void kvm_vmx_return(void);
 
 	if (!init_rmode_tss(vcpu->kvm)) {
@@ -1140,18 +1141,18 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
 	}
 	printk(KERN_DEBUG "kvm: msrs: %d\n", vcpu->nmsrs);
 
-	nr_good_msrs = vcpu->nmsrs - NR_BAD_MSRS;
+	nr_sw_save_msrs = vcpu->nmsrs - NR_HW_SAVE_MSRS;
 	vmcs_writel(VM_ENTRY_MSR_LOAD_ADDR,
-		    virt_to_phys(vcpu->guest_msrs + NR_BAD_MSRS));
+		    virt_to_phys(vcpu->guest_msrs + nr_sw_save_msrs));
 	vmcs_writel(VM_EXIT_MSR_STORE_ADDR,
-		    virt_to_phys(vcpu->guest_msrs + NR_BAD_MSRS));
+		    virt_to_phys(vcpu->guest_msrs + nr_sw_save_msrs));
 	vmcs_writel(VM_EXIT_MSR_LOAD_ADDR,
-		    virt_to_phys(vcpu->host_msrs + NR_BAD_MSRS));
+		    virt_to_phys(vcpu->host_msrs + nr_sw_save_msrs));
 	vmcs_write32_fixedbits(MSR_IA32_VMX_EXIT_CTLS, VM_EXIT_CONTROLS,
 		     	       (HOST_IS_64 << 9));  /* 22.2,1, 20.7.1 */
-	vmcs_write32(VM_EXIT_MSR_STORE_COUNT, nr_good_msrs); /* 22.2.2 */
-	vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, nr_good_msrs);  /* 22.2.2 */
-	vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, nr_good_msrs); /* 22.2.2 */
+	vmcs_write32(VM_EXIT_MSR_STORE_COUNT, NR_HW_SAVE_MSRS); /* 22.2.2 */
+	vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, NR_HW_SAVE_MSRS);  /* 22.2.2 */
+	vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, NR_HW_SAVE_MSRS); /* 22.2.2 */
 
 
 	/* 22.2.1, 20.8.1 */
@@ -1732,6 +1733,9 @@ static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	int fs_gs_ldt_reload_needed;
 	int r;
 
+	save_msrs(vcpu->host_msrs, vcpu->nmsrs);
+	load_msrs(vcpu->guest_msrs, vcpu->nmsrs - NR_HW_SAVE_MSRS);
+
 again:
 	/*
 	 * Set host fs and gs selectors.  Unfortunately, 22.2.3 does not
@@ -1766,9 +1770,6 @@ again:
 	fx_save(vcpu->host_fx_image);
 	fx_restore(vcpu->guest_fx_image);
 
-	save_msrs(vcpu->host_msrs, vcpu->nmsrs);
-	load_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
-
 	asm (
 		/* Store host registers */
 		"pushf \n\t"
@@ -1911,9 +1912,6 @@ again:
 	}
 	++kvm_stat.exits;
 
-	save_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
-	load_msrs(vcpu->host_msrs, NR_BAD_MSRS);
-
 	fx_save(vcpu->guest_fx_image);
 	fx_restore(vcpu->host_fx_image);
 	vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
@@ -1939,14 +1937,14 @@ again:
 			/* Give scheduler a change to reschedule. */
 			if (signal_pending(current)) {
 				++kvm_stat.signal_exits;
-				post_kvm_run_save(vcpu, kvm_run);
-				return -EINTR;
+ 				r = -EINTR;
+ 				goto out;
 			}
 
 			if (dm_request_for_irq_injection(vcpu, kvm_run)) {
 				++kvm_stat.request_irq_exits;
-				post_kvm_run_save(vcpu, kvm_run);
-				return -EINTR;
+ 				r = -EINTR;
+ 				goto out;
 			}
 
 			kvm_resched(vcpu);
@@ -1954,6 +1952,10 @@ again:
 		}
 	}
 
+out:
+	save_msrs(vcpu->guest_msrs, vcpu->nmsrs - NR_HW_SAVE_MSRS);
+	load_msrs(vcpu->host_msrs, vcpu->nmsrs - NR_HW_SAVE_MSRS);
+
 	post_kvm_run_save(vcpu, kvm_run);
 	return r;
 }

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

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

A message that is not in the archive (sent off-list or not yet received): 10EA09EFD8728347A513008B6B0DA77A01599D74-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org

#13 lore raw

Re: [PATCH] Remove redundant MSR save/restore

Quoted 3 lines · Eddie

This patch is to remove the redundant MSR save/restore at lightweight VM EXIT time. With this patch VMX guest KB performance can increase 17-37%.

There is a similar patch already in kvm-20 (which takes a slightly different approach of changing nr_good_msrs depending on the mode).

However, the part that hoists the software msr saving above the vmentry loop is not in my tree, and it does look good. It also makes sense to use software save/load for the msrs that only matter to userspace.

Quoted 4 lines

(I only tested it on KVM-18 since the git tree still has problem in my side, but I'd like to post this earlier to collect more feedback) Thanks, eddie

Please let me know if I can do anything to help with the git problem. I also suggest subscribing to kvm-commits so that you can see the work on my tree.

Also, please post patches *both* inline and as attachments :) - inline makes it easy to review and comment, and attachments to prevent mangling (this only applies to those with broken mailers -- a normal mailer will set the attachments content disposition to 'inline', which lets thunderbird show it as normal text).

Signature · 8 lines
error compiling committee.c: too many arguments to function


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

A message that is not in the archive (sent off-list or not yet received): 462F0E90.8010307-atKUWr5tajBWk0Htik3J/[email protected]

#15 lore raw

Re: [PATCH] Remove redundant MSR save/restore

Avi:
Thanks!
Another found is that HOST_FS/GS_BASE & MSR_FS/GS_BASE
save/restore is quit expansive. I am not sure why it needs to be save/restored given that the VMCS regster will be loaded into FS/gs at VM EXIT time automatically by HW and will not be changed during guest execution time. The MSR is also same (guest change will be trap and emulated in guest context only).
If I remove HOST_FS/GS_BASE save/restore out to be only matter
to userspace, I can get 15% performance gain for KB. But I am not sure yet if there is any potential issue.

thanks, eddie

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

A message that is not in the archive (sent off-list or not yet received): 10EA09EFD8728347A513008B6B0DA77A01599E01-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org

#17 lore raw

Re: [PATCH] Remove redundant MSR save/restore

Quoted 12 lines · Eddie

Avi:
Thanks!
Another found is that HOST_FS/GS_BASE & MSR_FS/GS_BASE
save/restore is quit expansive. I am not sure why it needs to be save/restored given that the VMCS regster will be loaded into FS/gs at VM EXIT time automatically by HW and will not be changed during guest execution time. The MSR is also same (guest change will be trap and emulated in guest context only).
If I remove HOST_FS/GS_BASE save/restore out to be only matter
to userspace, I can get 15% performance gain for KB. But I am not sure yet if there is any potential issue.

Quoted 2 lines

thanks, eddie

I don't see issues with moving them outside the loop, as long as preemption is disabled.

Signature · 8 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
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/
#18 lore raw

PATCH 1/1 Remove heavy is_empty_shadow_page call.

In reply to a message not in the archive

A minor patch to avoid heavy is_empty_shadow_page for release version.

drivers/kvm/mmu.c +0 -0
index e85b4c7..58fdd7b 100644
@@ -52,11 +52,15 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu,

const char *msg) {}
static int dbg = 1;
#endif

+#if defined(MMU_DEBUG)
+#define ASSERT(x) do { } while (0)
+#else
#define ASSERT(x)

\
        if (!(x)) {
\
                printk(KERN_WARNING "assertion failed %s:%d: %s\n",
\
                       __FILE__, __LINE__, #x);
\
        }

+#endif

#define PT64_PT_BITS 9
#define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS)

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

A message that is not in the archive (sent off-list or not yet received): 10EA09EFD8728347A513008B6B0DA77A01599D2B-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org

#20 lore raw

Re: [PATCH] Remove heavy is_empty_shadow_page call.

Quoted 4 lines · Eddie

A minor patch to avoid heavy is_empty_shadow_page for release version.

Please resend as attachment, you email client mangled the patch.

Signature · 8 lines
error compiling committee.c: too many arguments to function


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

A message that is not in the archive (sent off-list or not yet received): 462F0B40.9060109-atKUWr5tajBWk0Htik3J/[email protected]

#22 lore raw

Re: [PATCH] Remove heavy is_empty_shadow_page call.

Sorry for that, attached now.
Eddie

-----Original Message-----
From: Avi Kivity [mailto:avi-atKUWr5tajBWk0Htik3J/[email protected]]
Sent: 2007年4月25日 16:03
To: Dong, Eddie
Cc: kvm-devel
Subject: Re: [kvm-devel] [PATCH] Remove heavy is_empty_shadow_page call.

Quoted 4 lines · Eddie

A minor patch to avoid heavy is_empty_shadow_page for release version.

Please resend as attachment, you email client mangled the patch.

Signature · 1 line
error compiling committee.c: too many arguments to function

commit 2578b40853dc8601ffaf76bac40a40653b2e8639

Author: Yaozu Dong <[email protected]>
Date:   Wed Apr 25 14:17:25 2007 +0800

Avoid heavy ASSERT at non debug mode.

drivers/kvm/mmu.c +4 -0
index e85b4c7..58fdd7b 100644
@@ -52,11 +52,15 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) {}
 static int dbg = 1;
 #endif
 
+#if defined(MMU_DEBUG)
+#define ASSERT(x) do { } while (0)
+#else
 #define ASSERT(x)							\
 	if (!(x)) {							\
 		printk(KERN_WARNING "assertion failed %s:%d: %s\n",	\
 		       __FILE__, __LINE__, #x);				\
 	}
+#endif
 
 #define PT64_PT_BITS 9
 #define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS)

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

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

A message that is not in the archive (sent off-list or not yet received): 10EA09EFD8728347A513008B6B0DA77A01599D87-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org

Applied
#24 lore raw

Re: [PATCH] Remove heavy is_empty_shadow_page call.

Quoted 2 lines · Eddie

Sorry for that, attached now.

Applied. Please provide a Signed-off-by: line in the future.

Signature · 1 line
error compiling committee.c: too many arguments to function

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

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#25 lore raw

Re: [PATCH] Remove heavy is_empty_shadow_page call.

In reply to a message not in the archive
Quoted 8 lines · Eddie

A minor patch to avoid heavy is_empty_shadow_page for release version.

drivers/kvm/mmu.c +0 -0
index e85b4c7..58fdd7b 100644

drivers/kvm/mmu.c static void kvm_mmu_audit(struct kvm_vcpu *vcpu, · line 57

Quoted 6 lines
drivers/kvm/mmu.c +2 -0
@@ -52,11 +52,15 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu,
 const char *msg) {}
 static int dbg = 1;
 #endif
 
+#if defined(MMU_DEBUG)
+#define ASSERT(x) do { } while (0)

I suppose you meant the opposite, !defined(...)?

Why would anyone want to turn off assertions in debug mode?

Quoted 15 lines
drivers/kvm/mmu.c +1 -0
+#else
 #define ASSERT(x)
 \
        if (!(x)) {
 \
                printk(KERN_WARNING "assertion failed %s:%d: %s\n",
 \
                       __FILE__, __LINE__, #x);
\
        }

+#endif

#define PT64_PT_BITS 9
#define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS)

Quoted 9 lines

-------------------------------------------------------------------------
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/
_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

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

A message that is not in the archive (sent off-list or not yet received): [email protected]

#27 lore raw

Re: [PATCH] Remove heavy is_empty_shadow_page call.

O, yes typo at different tree porting time.

Quoted 31 lines · Michael Riepe
Quoted 9 lines · Eddie

A minor patch to avoid heavy is_empty_shadow_page for release version.

drivers/kvm/mmu.c +0 -0
index e85b4c7..58fdd7b 100644

drivers/kvm/mmu.c static void kvm_mmu_audit(struct kvm_vcpu *vcpu, · line 56

Quoted 5 lines
drivers/kvm/mmu.c +2 -0
@@ -52,11 +52,15 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu,
 const char *msg) {} static int dbg = 1;
 #endif
 
+#if defined(MMU_DEBUG)
+#define ASSERT(x) do { } while (0)

I suppose you meant the opposite, !defined(...)?

Why would anyone want to turn off assertions in debug mode?

Quoted 11 lines
drivers/kvm/mmu.c +2 -0
+#else
 #define ASSERT(x)
 \
        if (!(x)) {
 \
                printk(KERN_WARNING "assertion failed %s:%d: %s\n", \
                       __FILE__, __LINE__, #x);
 \
        }
+#endif
Quoted 4 lines
Quoted 4 lines

#define PT64_PT_BITS 9
#define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS)

------------------------------------------------------------------------
-

Quoted 8 lines
Quoted 8 lines

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/
_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

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

#28 lore raw

Re: [PATCH] Remove heavy is_empty_shadow_page call.

In reply to a message not in the archive
Quoted 14 lines · Michael Riepe
Quoted 12 lines · Eddie

A minor patch to avoid heavy is_empty_shadow_page for release version.

drivers/kvm/mmu.c +0 -0
index e85b4c7..58fdd7b 100644
@@ -52,11 +52,15 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu,
 const char *msg) {}
 static int dbg = 1;
 #endif
 
Quoted 9 lines

drivers/kvm/mmu.c static void kvm_mmu_audit(struct kvm_vcpu *vcpu, · line 58

Quoted 3 lines
drivers/kvm/mmu.c +2 -0
+#if defined(MMU_DEBUG)
+#define ASSERT(x) do { } while (0)
 

I suppose you meant the opposite, !defined(...)?

Why would anyone want to turn off assertions in debug mode?

Good catch. I committed a fix.

Signature · 8 lines
error compiling committee.c: too many arguments to function


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