aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/kvm_main.c
diff options
context:
space:
mode:
authorEddie Dong <eddie.dong@intel.com>2007-05-21 00:28:09 -0400
committerAvi Kivity <avi@qumranet.com>2007-07-16 05:05:42 -0400
commit2cc51560aed0edb291341089d3475e1fbe8bfd04 (patch)
treee4fd63e0e79613fbb7e475dcdd0ea01c370e02a8 /drivers/kvm/kvm_main.c
parentf2be4dd65437c60a4eb222bc40bc8caded62631a (diff)
KVM: VMX: Avoid saving and restoring msr_efer on lightweight vmexit
MSR_EFER.LME/LMA bits are automatically save/restored by VMX hardware, KVM only needs to save NX/SCE bits at time of heavy weight VM Exit. But clearing NX bits in host envirnment may cause system hang if the host page table is using EXB bits, thus we leave NX bits as it is. If Host NX=1 and guest NX=0, we can do guest page table EXB bits check before inserting a shadow pte (though no guest is expecting to see this kind of gp fault). If host NX=0, we present guest no Execute-Disable feature to guest, thus no host NX=0, guest NX=1 combination. This patch reduces raw vmexit time by ~27%. Me: fix compile warnings on i386. Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r--drivers/kvm/kvm_main.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 095d673b9efb..af07cd539bba 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -73,6 +73,7 @@ static struct kvm_stats_debugfs_item {
73 { "request_irq", STAT_OFFSET(request_irq_exits) }, 73 { "request_irq", STAT_OFFSET(request_irq_exits) },
74 { "irq_exits", STAT_OFFSET(irq_exits) }, 74 { "irq_exits", STAT_OFFSET(irq_exits) },
75 { "light_exits", STAT_OFFSET(light_exits) }, 75 { "light_exits", STAT_OFFSET(light_exits) },
76 { "efer_reload", STAT_OFFSET(efer_reload) },
76 { NULL } 77 { NULL }
77}; 78};
78 79
@@ -2378,6 +2379,27 @@ out:
2378 return r; 2379 return r;
2379} 2380}
2380 2381
2382static void cpuid_fix_nx_cap(struct kvm_vcpu *vcpu)
2383{
2384 u64 efer;
2385 int i;
2386 struct kvm_cpuid_entry *e, *entry;
2387
2388 rdmsrl(MSR_EFER, efer);
2389 entry = NULL;
2390 for (i = 0; i < vcpu->cpuid_nent; ++i) {
2391 e = &vcpu->cpuid_entries[i];
2392 if (e->function == 0x80000001) {
2393 entry = e;
2394 break;
2395 }
2396 }
2397 if (entry && (entry->edx & EFER_NX) && !(efer & EFER_NX)) {
2398 entry->edx &= ~(1 << 20);
2399 printk(KERN_INFO ": guest NX capability removed\n");
2400 }
2401}
2402
2381static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, 2403static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
2382 struct kvm_cpuid *cpuid, 2404 struct kvm_cpuid *cpuid,
2383 struct kvm_cpuid_entry __user *entries) 2405 struct kvm_cpuid_entry __user *entries)
@@ -2392,6 +2414,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
2392 cpuid->nent * sizeof(struct kvm_cpuid_entry))) 2414 cpuid->nent * sizeof(struct kvm_cpuid_entry)))
2393 goto out; 2415 goto out;
2394 vcpu->cpuid_nent = cpuid->nent; 2416 vcpu->cpuid_nent = cpuid->nent;
2417 cpuid_fix_nx_cap(vcpu);
2395 return 0; 2418 return 0;
2396 2419
2397out: 2420out: