From: Sheng Yang <sheng.yang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Subject: [PATCH] KVM: VMX: Fix repeatly allocate of apic access page
Date: Tue, 6 Nov 2007 17:55:14 +0800 [thread overview]
Message-ID: <200711061755.14444.sheng.yang@intel.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 5039 bytes --]
From 617412380eec67503d45cd91860b756f15293e73 Mon Sep 17 00:00:00 2001
From: Sheng Yang <sheng.yang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Date: Tue, 6 Nov 2007 11:37:44 +0800
Subject: [PATCH] KVM: VMX: Fix repeatly allocate of apic access page
For 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 FlexPriority.
This patch fixed this issue.
---
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
--- 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
--- 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.
*/
-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;
@@ -307,8 +309,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;
@@ -318,7 +318,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;
@@ -329,7 +329,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 */
@@ -343,7 +343,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));
@@ -360,7 +360,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) {
@@ -383,7 +383,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);
}
@@ -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);
- 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,
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 42e7fad..da3a339 100644
--- 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;
- int r;
+ int r = 0;
- r = -EFAULT;
+ mutex_lock(&kvm->lock);
+ if (kvm->apic_access_page)
+ goto out;
kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT;
kvm_userspace_mem.flags = 0;
kvm_userspace_mem.guest_phys_addr = 0xfee00000ULL;
kvm_userspace_mem.memory_size = PAGE_SIZE;
- r = kvm_set_memory_region(kvm, &kvm_userspace_mem, 0);
+ r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0);
if (r)
- return r;
+ goto out;
kvm->apic_access_page = gfn_to_page(kvm, 0xfee00);
- return 0;
+out:
+ mutex_unlock(&kvm->lock);
+ return r;
}
/*
--
1.5.2
[-- Attachment #2: 0001-KVM-VMX-Fix-repeatly-allocate-of-apic-access-page.patch --]
[-- Type: text/x-diff, Size: 5037 bytes --]
From 617412380eec67503d45cd91860b756f15293e73 Mon Sep 17 00:00:00 2001
From: Sheng Yang <sheng.yang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Date: Tue, 6 Nov 2007 11:37:44 +0800
Subject: [PATCH] KVM: VMX: Fix repeatly allocate of apic access page
For 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 FlexPriority.
This patch fixed this issue.
---
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
--- 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
--- 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.
*/
-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;
@@ -307,8 +309,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;
@@ -318,7 +318,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;
@@ -329,7 +329,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 */
@@ -343,7 +343,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));
@@ -360,7 +360,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) {
@@ -383,7 +383,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);
}
@@ -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);
- 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,
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 42e7fad..da3a339 100644
--- 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;
- int r;
+ int r = 0;
- r = -EFAULT;
+ mutex_lock(&kvm->lock);
+ if (kvm->apic_access_page)
+ goto out;
kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT;
kvm_userspace_mem.flags = 0;
kvm_userspace_mem.guest_phys_addr = 0xfee00000ULL;
kvm_userspace_mem.memory_size = PAGE_SIZE;
- r = kvm_set_memory_region(kvm, &kvm_userspace_mem, 0);
+ r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0);
if (r)
- return r;
+ goto out;
kvm->apic_access_page = gfn_to_page(kvm, 0xfee00);
- return 0;
+out:
+ mutex_unlock(&kvm->lock);
+ return r;
}
/*
--
1.5.2
[-- Attachment #3: Type: text/plain, Size: 314 bytes --]
-------------------------------------------------------------------------
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/
[-- Attachment #4: Type: text/plain, Size: 186 bytes --]
_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel
next reply other threads:[~2007-11-06 9:55 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-11-06 9:55 Sheng Yang [this message]
[not found] ` <200711061755.14444.sheng.yang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2007-11-06 10:04 ` [PATCH] KVM: VMX: Fix repeatly allocate of apic access page Avi Kivity
-- strict thread matches above, loose matches on Subject: below --
2007-11-06 3:00 Sheng Yang
[not found] ` <200711061100.35700.sheng.yang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2007-11-06 9:23 ` Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200711061755.14444.sheng.yang@intel.com \
--to=sheng.yang-ral2jqcrhueavxtiumwx3w@public.gmane.org \
--cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.