From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sheng Yang Subject: [PATCH] KVM: VMX: Fix repeatly allocate of apic access page Date: Tue, 6 Nov 2007 17:55:14 +0800 Message-ID: <200711061755.14444.sheng.yang@intel.com> Mime-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_CoDMHg5dIfsq7Kw" To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Return-path: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Errors-To: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org List-Id: kvm.vger.kernel.org --Boundary-00=_CoDMHg5dIfsq7Kw Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline =46rom 617412380eec67503d45cd91860b756f15293e73 Mon Sep 17 00:00:00 2001 =46rom: Sheng Yang Date: Tue, 6 Nov 2007 11:37:44 +0800 Subject: [PATCH] KVM: VMX: Fix repeatly allocate of apic access page =46or SMP guest, alloc_apic_access_page() would be called more than once. So only the last one works, causing SMP guest can't benifit from FlexPriori= ty. This patch fixed this issue. =2D-- drivers/kvm/kvm.h | 3 +++ drivers/kvm/kvm_main.c | 38 ++++++++++++++++++++++++-------------- drivers/kvm/vmx.c | 14 +++++++++----- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index 6b3b5e9..3ebfb19 100644 =2D-- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h @@ -524,6 +524,9 @@ int is_error_page(struct page *page); 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); gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn); struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn); void kvm_release_page(struct page *page); diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index af7090f..d332a77 100644 =2D-- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -277,10 +277,12 @@ static int kvm_vm_release(struct inode *inode, struct= =20 file *filp) * space. * * Discontiguous memory is allowed, mostly for framebuffers. + * + * Must be called holding kvm->lock. */ =2Dint kvm_set_memory_region(struct kvm *kvm, =2D struct kvm_userspace_memory_region *mem, =2D 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; @@ -307,8 +309,6 @@ int kvm_set_memory_region(struct kvm *kvm, if (!npages) mem->flags &=3D ~KVM_MEM_LOG_DIRTY_PAGES; =20 =2D mutex_lock(&kvm->lock); =2D new =3D old =3D *memslot; =20 new.base_gfn =3D base_gfn; @@ -318,7 +318,7 @@ int kvm_set_memory_region(struct kvm *kvm, /* Disallow changing a memory slot's size. */ r =3D -EINVAL; if (npages && old.npages && npages !=3D old.npages) =2D goto out_unlock; + goto out_free; =20 /* Check for overlaps */ r =3D -EEXIST; @@ -329,7 +329,7 @@ int kvm_set_memory_region(struct kvm *kvm, continue; if (!((base_gfn + npages <=3D s->base_gfn) || (base_gfn >=3D s->base_gfn + s->npages))) =2D goto out_unlock; + goto out_free; } =20 /* Free page dirty bitmap if unneeded */ @@ -343,7 +343,7 @@ int kvm_set_memory_region(struct kvm *kvm, new.rmap =3D vmalloc(npages * sizeof(struct page *)); =20 if (!new.rmap) =2D goto out_unlock; + goto out_free; =20 memset(new.rmap, 0, npages * sizeof(*new.rmap)); =20 @@ -360,7 +360,7 @@ int kvm_set_memory_region(struct kvm *kvm, up_write(¤t->mm->mmap_sem); =20 if (IS_ERR((void *)new.userspace_addr)) =2D goto out_unlock; + goto out_free; } } else { if (!old.user_alloc && old.rmap) { @@ -383,7 +383,7 @@ int kvm_set_memory_region(struct kvm *kvm, =20 new.dirty_bitmap =3D vmalloc(dirty_bytes); if (!new.dirty_bitmap) =2D goto out_unlock; + goto out_free; memset(new.dirty_bitmap, 0, dirty_bytes); } =20 @@ -413,18 +413,28 @@ int kvm_set_memory_region(struct kvm *kvm, kvm_mmu_slot_remove_write_access(kvm, mem->slot); kvm_flush_remote_tlbs(kvm); =20 =2D mutex_unlock(&kvm->lock); =2D kvm_free_physmem_slot(&old, &new); return 0; =20 =2Dout_unlock: =2D mutex_unlock(&kvm->lock); +out_free: kvm_free_physmem_slot(&new, &old); out: return r; =20 } +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 =3D __kvm_set_memory_region(kvm, mem, user_alloc); + mutex_unlock(&kvm->lock); + return r; +} EXPORT_SYMBOL_GPL(kvm_set_memory_region); =20 int kvm_vm_ioctl_set_memory_region(struct kvm *kvm, diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index 42e7fad..da3a339 100644 =2D-- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c @@ -1463,18 +1463,22 @@ static void seg_setup(int seg) static int alloc_apic_access_page(struct kvm *kvm) { struct kvm_userspace_memory_region kvm_userspace_mem; =2D int r; + int r =3D 0; =20 =2D r =3D -EFAULT; + mutex_lock(&kvm->lock); + if (kvm->apic_access_page) + goto out; kvm_userspace_mem.slot =3D APIC_ACCESS_PAGE_PRIVATE_MEMSLOT; kvm_userspace_mem.flags =3D 0; kvm_userspace_mem.guest_phys_addr =3D 0xfee00000ULL; kvm_userspace_mem.memory_size =3D PAGE_SIZE; =2D r =3D kvm_set_memory_region(kvm, &kvm_userspace_mem, 0); + r =3D __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0); if (r) =2D return r; + goto out; kvm->apic_access_page =3D gfn_to_page(kvm, 0xfee00); =2D return 0; +out: + mutex_unlock(&kvm->lock); + return r; } =20 /* =2D-=20 1.5.2 --Boundary-00=_CoDMHg5dIfsq7Kw Content-Type: text/x-diff; charset="utf-8"; name="0001-KVM-VMX-Fix-repeatly-allocate-of-apic-access-page.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-KVM-VMX-Fix-repeatly-allocate-of-apic-access-page.patch" =46rom 617412380eec67503d45cd91860b756f15293e73 Mon Sep 17 00:00:00 2001 =46rom: Sheng Yang Date: Tue, 6 Nov 2007 11:37:44 +0800 Subject: [PATCH] KVM: VMX: Fix repeatly allocate of apic access page =46or SMP guest, alloc_apic_access_page() would be called more than once. So only the last one works, causing SMP guest can't benifit from FlexPriori= ty. This patch fixed this issue. =2D-- drivers/kvm/kvm.h | 3 +++ drivers/kvm/kvm_main.c | 38 ++++++++++++++++++++++++-------------- drivers/kvm/vmx.c | 14 +++++++++----- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index 6b3b5e9..3ebfb19 100644 =2D-- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h @@ -524,6 +524,9 @@ int is_error_page(struct page *page); 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); gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn); struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn); void kvm_release_page(struct page *page); diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index af7090f..d332a77 100644 =2D-- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -277,10 +277,12 @@ static int kvm_vm_release(struct inode *inode, struct= file *filp) * space. * * Discontiguous memory is allowed, mostly for framebuffers. + * + * Must be called holding kvm->lock. */ =2Dint kvm_set_memory_region(struct kvm *kvm, =2D struct kvm_userspace_memory_region *mem, =2D 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; @@ -307,8 +309,6 @@ int kvm_set_memory_region(struct kvm *kvm, if (!npages) mem->flags &=3D ~KVM_MEM_LOG_DIRTY_PAGES; =20 =2D mutex_lock(&kvm->lock); =2D new =3D old =3D *memslot; =20 new.base_gfn =3D base_gfn; @@ -318,7 +318,7 @@ int kvm_set_memory_region(struct kvm *kvm, /* Disallow changing a memory slot's size. */ r =3D -EINVAL; if (npages && old.npages && npages !=3D old.npages) =2D goto out_unlock; + goto out_free; =20 /* Check for overlaps */ r =3D -EEXIST; @@ -329,7 +329,7 @@ int kvm_set_memory_region(struct kvm *kvm, continue; if (!((base_gfn + npages <=3D s->base_gfn) || (base_gfn >=3D s->base_gfn + s->npages))) =2D goto out_unlock; + goto out_free; } =20 /* Free page dirty bitmap if unneeded */ @@ -343,7 +343,7 @@ int kvm_set_memory_region(struct kvm *kvm, new.rmap =3D vmalloc(npages * sizeof(struct page *)); =20 if (!new.rmap) =2D goto out_unlock; + goto out_free; =20 memset(new.rmap, 0, npages * sizeof(*new.rmap)); =20 @@ -360,7 +360,7 @@ int kvm_set_memory_region(struct kvm *kvm, up_write(¤t->mm->mmap_sem); =20 if (IS_ERR((void *)new.userspace_addr)) =2D goto out_unlock; + goto out_free; } } else { if (!old.user_alloc && old.rmap) { @@ -383,7 +383,7 @@ int kvm_set_memory_region(struct kvm *kvm, =20 new.dirty_bitmap =3D vmalloc(dirty_bytes); if (!new.dirty_bitmap) =2D goto out_unlock; + goto out_free; memset(new.dirty_bitmap, 0, dirty_bytes); } =20 @@ -413,18 +413,28 @@ int kvm_set_memory_region(struct kvm *kvm, kvm_mmu_slot_remove_write_access(kvm, mem->slot); kvm_flush_remote_tlbs(kvm); =20 =2D mutex_unlock(&kvm->lock); =2D kvm_free_physmem_slot(&old, &new); return 0; =20 =2Dout_unlock: =2D mutex_unlock(&kvm->lock); +out_free: kvm_free_physmem_slot(&new, &old); out: return r; =20 } +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 =3D __kvm_set_memory_region(kvm, mem, user_alloc); + mutex_unlock(&kvm->lock); + return r; +} EXPORT_SYMBOL_GPL(kvm_set_memory_region); =20 int kvm_vm_ioctl_set_memory_region(struct kvm *kvm, diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index 42e7fad..da3a339 100644 =2D-- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c @@ -1463,18 +1463,22 @@ static void seg_setup(int seg) static int alloc_apic_access_page(struct kvm *kvm) { struct kvm_userspace_memory_region kvm_userspace_mem; =2D int r; + int r =3D 0; =20 =2D r =3D -EFAULT; + mutex_lock(&kvm->lock); + if (kvm->apic_access_page) + goto out; kvm_userspace_mem.slot =3D APIC_ACCESS_PAGE_PRIVATE_MEMSLOT; kvm_userspace_mem.flags =3D 0; kvm_userspace_mem.guest_phys_addr =3D 0xfee00000ULL; kvm_userspace_mem.memory_size =3D PAGE_SIZE; =2D r =3D kvm_set_memory_region(kvm, &kvm_userspace_mem, 0); + r =3D __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0); if (r) =2D return r; + goto out; kvm->apic_access_page =3D gfn_to_page(kvm, 0xfee00); =2D return 0; +out: + mutex_unlock(&kvm->lock); + return r; } =20 /* =2D-=20 1.5.2 --Boundary-00=_CoDMHg5dIfsq7Kw Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ --Boundary-00=_CoDMHg5dIfsq7Kw Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ kvm-devel mailing list kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/kvm-devel --Boundary-00=_CoDMHg5dIfsq7Kw--