[PATCH] Remove redundant MSR save/restore

Dong, Eddie
2007-04-25T08:03:07Z

[-- Attachment #1: Type: text/plain, Size: 302 bytes --]

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

[-- Attachment #2: msr.diff --]
[-- Type: application/octet-stream, Size: 4130 bytes --]

commit 11554c848e14f5322210c640e4a7ddeabe961282
Author: Yaozu Dong <Eddie.dong@intel.com>
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.

diff --git a/drivers/kvm/kvm_vmx.h b/drivers/kvm/kvm_vmx.h
index d139f73..f1bf7ad 100644
--- a/drivers/kvm/kvm_vmx.h
+++ b/drivers/kvm/kvm_vmx.h
@@ -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
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index fbbf9d6..3d2176f 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -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;
}

[-- Attachment #3: Type: text/plain, Size: 286 bytes --]

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

[-- Attachment #4: Type: text/plain, Size: 186 bytes --]

_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org