Re: [PATCH][UPDATE] shortcut for lightweight VM Exit

Dong, Eddie
2007-04-30T11:23:09Z

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

Avi Kivity wrote:
> Dong, Eddie wrote:
>> This patch provides short cut handling for light weight VM Exit,
>> which can boost KB performance 11% under FC5 guest.
>> Any comments?
>
> While the patch looks good, it kills FC6 x86_64 boot with a double
> fault. Guest kernel is 2.6.18-1.2798. dmesg says
>
> inject_page_fault: double fault 0x7fff79b58fd8 @ 0xffffffff8025cca1
>
I think I know the reason, the SYSCALL_MASK & LSTAR update in guest
needs to
update the physical side MSR after this patch. With this update in
vmx_set_msr,
I get it up on a RHEL5U 64 bits guest but no time to check the detail
performance
gain yet. (will report after May day national holiday 5/1--5/8 in PRC)

BTW, I have another patch in hand to further reduce MSR save/restore and
thus
improve performance more for lightweight VM Exit. Base on my observation
for FC5 32 bits
guest, 93% VM Exit will fall into the lightweight path.

Thx, eddie

[-- Attachment #2: lightweight4.patch --]
[-- Type: application/octet-stream, Size: 4149 bytes --]

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 41634fd..11eb25e 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -251,6 +251,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 4c5b8db..0945c7f 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -71,6 +71,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 74d058e..10ff0c3 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -478,6 +478,14 @@ 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);
@@ -1815,7 +1823,6 @@ static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
int fs_gs_ldt_reload_needed;
int r;

-again:
/*
* Set host fs and gs selectors. Unfortunately, 22.2.3 does not
* allow segment selectors with cpl > 0 or ti == 1.
@@ -1858,6 +1865,7 @@ again:
}
#endif

+again:
asm (
/* Store host registers */
"pushf \n\t"
@@ -1977,6 +1985,47 @@ again:
[cr2]"i"(offsetof(struct kvm_vcpu, cr2))
: "cc", "memory" );

+ ++vcpu->stat.exits;
+
+ vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
+
+ asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
+
+ if (fail) {
+ kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+ kvm_run->fail_entry.hardware_entry_failure_reason
+ = vmcs_read32(VM_INSTRUCTION_ERROR);
+ r = 0;
+ } else {
+ /*
+ * Profile KVM exit RIPs:
+ */
+ if (unlikely(prof_on == KVM_PROFILING))
+ profile_hit(KVM_PROFILING, (void *)vmcs_readl(GUEST_RIP));
+
+ vcpu->launched = 1;
+ r = kvm_handle_exit(kvm_run, vcpu);
+ if (r > 0) {
+ r = -EINTR;
+ kvm_run->exit_reason = KVM_EXIT_INTR;
+ /* Give scheduler a change to reschedule. */
+ if (signal_pending(current)) {
+ ++vcpu->stat.signal_exits;
+ goto out;
+ }
+
+ if (dm_request_for_irq_injection(vcpu, kvm_run)) {
+ ++vcpu->stat.request_irq_exits;
+ goto out;
+ }
+ if (!need_resched()) {
+ ++vcpu->stat.light_exits;
+ 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
@@ -1998,8 +2047,6 @@ again:

reload_tss();
}
- ++vcpu->stat.exits;
-
#ifdef CONFIG_X86_64
if (is_long_mode(vcpu)) {
save_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
@@ -2012,45 +2059,6 @@ again:
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));
-
- if (fail) {
- kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
- kvm_run->fail_entry.hardware_entry_failure_reason
- = vmcs_read32(VM_INSTRUCTION_ERROR);
- r = 0;
- } else {
- /*
- * Profile KVM exit RIPs:
- */
- if (unlikely(prof_on == KVM_PROFILING))
- profile_hit(KVM_PROFILING, (void *)vmcs_readl(GUEST_RIP));
-
- vcpu->launched = 1;
- r = kvm_handle_exit(kvm_run, vcpu);
- if (r > 0) {
- /* Give scheduler a change to reschedule. */
- if (signal_pending(current)) {
- ++vcpu->stat.signal_exits;
- post_kvm_run_save(vcpu, kvm_run);
- kvm_run->exit_reason = KVM_EXIT_INTR;
- return -EINTR;
- }
-
- if (dm_request_for_irq_injection(vcpu, kvm_run)) {
- ++vcpu->stat.request_irq_exits;
- post_kvm_run_save(vcpu, kvm_run);
- kvm_run->exit_reason = KVM_EXIT_INTR;
- return -EINTR;
- }
-
- kvm_resched(vcpu);
- goto again;
- }
- }
-
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