diff options
author | Sheng Yang <sheng.yang@intel.com> | 2007-10-29 09:40:42 +0800 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 17:52:58 +0200 |
commit | f78e0e2ee498e8f847500b565792c7d7634dcf54 (patch) | |
tree | dfd8f35883b40939a1ec013e27e6303af06d3e77 /drivers/kvm/kvm_main.c | |
parent | a03490ed29d2771c675d4d9c0ffe22e19a1757f3 (diff) | |
download | op-kernel-dev-f78e0e2ee498e8f847500b565792c7d7634dcf54.zip op-kernel-dev-f78e0e2ee498e8f847500b565792c7d7634dcf54.tar.gz |
KVM: VMX: Enable memory mapped TPR shadow (FlexPriority)
This patch based on CR8/TPR patch, and enable the TPR shadow (FlexPriority)
for 32bit Windows. Since TPR is accessed very frequently by 32bit
Windows, especially SMP guest, with FlexPriority enabled, we saw significant
performance gain.
Signed-off-by: Sheng Yang <sheng.yang@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.c | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 8f71257..ac5ed00 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -362,10 +362,12 @@ EXPORT_SYMBOL_GPL(fx_init); * space. * * Discontiguous memory is allowed, mostly for framebuffers. + * + * Must be called holding kvm->lock. */ -int kvm_set_memory_region(struct kvm *kvm, - struct kvm_userspace_memory_region *mem, - int user_alloc) +int __kvm_set_memory_region(struct kvm *kvm, + struct kvm_userspace_memory_region *mem, + int user_alloc) { int r; gfn_t base_gfn; @@ -392,8 +394,6 @@ int kvm_set_memory_region(struct kvm *kvm, if (!npages) mem->flags &= ~KVM_MEM_LOG_DIRTY_PAGES; - mutex_lock(&kvm->lock); - new = old = *memslot; new.base_gfn = base_gfn; @@ -403,7 +403,7 @@ int kvm_set_memory_region(struct kvm *kvm, /* Disallow changing a memory slot's size. */ r = -EINVAL; if (npages && old.npages && npages != old.npages) - goto out_unlock; + goto out_free; /* Check for overlaps */ r = -EEXIST; @@ -414,7 +414,7 @@ int kvm_set_memory_region(struct kvm *kvm, continue; if (!((base_gfn + npages <= s->base_gfn) || (base_gfn >= s->base_gfn + s->npages))) - goto out_unlock; + goto out_free; } /* Free page dirty bitmap if unneeded */ @@ -428,7 +428,7 @@ int kvm_set_memory_region(struct kvm *kvm, new.rmap = vmalloc(npages * sizeof(struct page *)); if (!new.rmap) - goto out_unlock; + goto out_free; memset(new.rmap, 0, npages * sizeof(*new.rmap)); @@ -445,7 +445,7 @@ int kvm_set_memory_region(struct kvm *kvm, up_write(¤t->mm->mmap_sem); if (IS_ERR((void *)new.userspace_addr)) - goto out_unlock; + goto out_free; } } else { if (!old.user_alloc && old.rmap) { @@ -468,7 +468,7 @@ int kvm_set_memory_region(struct kvm *kvm, new.dirty_bitmap = vmalloc(dirty_bytes); if (!new.dirty_bitmap) - goto out_unlock; + goto out_free; memset(new.dirty_bitmap, 0, dirty_bytes); } @@ -498,18 +498,28 @@ int kvm_set_memory_region(struct kvm *kvm, kvm_mmu_slot_remove_write_access(kvm, mem->slot); kvm_flush_remote_tlbs(kvm); - mutex_unlock(&kvm->lock); - kvm_free_physmem_slot(&old, &new); return 0; -out_unlock: - mutex_unlock(&kvm->lock); +out_free: kvm_free_physmem_slot(&new, &old); out: return r; } +EXPORT_SYMBOL_GPL(__kvm_set_memory_region); + +int kvm_set_memory_region(struct kvm *kvm, + struct kvm_userspace_memory_region *mem, + int user_alloc) +{ + int r; + + mutex_lock(&kvm->lock); + r = __kvm_set_memory_region(kvm, mem, user_alloc); + mutex_unlock(&kvm->lock); + return r; +} EXPORT_SYMBOL_GPL(kvm_set_memory_region); int kvm_vm_ioctl_set_memory_region(struct kvm *kvm, @@ -888,14 +898,21 @@ static int emulator_read_emulated(unsigned long addr, memcpy(val, vcpu->mmio_data, bytes); vcpu->mmio_read_completed = 0; return X86EMUL_CONTINUE; - } else if (emulator_read_std(addr, val, bytes, vcpu) - == X86EMUL_CONTINUE) - return X86EMUL_CONTINUE; + } gpa = vcpu->mmu.gva_to_gpa(vcpu, addr); + + /* For APIC access vmexit */ + if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) + goto mmio; + + if (emulator_read_std(addr, val, bytes, vcpu) + == X86EMUL_CONTINUE) + return X86EMUL_CONTINUE; if (gpa == UNMAPPED_GVA) return X86EMUL_PROPAGATE_FAULT; +mmio: /* * Is this MMIO handled locally? */ @@ -938,9 +955,14 @@ static int emulator_write_emulated_onepage(unsigned long addr, return X86EMUL_PROPAGATE_FAULT; } + /* For APIC access vmexit */ + if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) + goto mmio; + if (emulator_write_phys(vcpu, gpa, val, bytes)) return X86EMUL_CONTINUE; +mmio: /* * Is this MMIO handled locally? */ |