From: Andrea Arcangeli <andrea@qumranet.com>
To: Avi Kivity <avi@qumranet.com>
Cc: Marcelo Tosatti <marcelo.tosatti@cyclades.com.br>, kvm@vger.kernel.org
Subject: [PATCH 3/6] kvm.git allow browsing memslots with mmu_lock
Date: Fri, 25 Jul 2008 16:32:03 +0200 [thread overview]
Message-ID: <20080725143203.GC8217@duo.random> (raw)
In-Reply-To: <20080725142639.GB8217@duo.random>
This allows reading memslots with only the mmu_lock hold for mmu
notifiers that runs in atomic context and with mmu_lock held.
Compared to previous versions I had to move this:
- if (mem->slot >= kvm->nmemslots)
- kvm->nmemslots = mem->slot + 1;
after the call to kvm_arch_flush_shadow but that's ok as they're
mutually exclusive: npages being null asks to remove the memslot and
you can't remove a memslot that doesn't exist yet even if there's no
explicit check that forbids it. In any case the ordering didn't seem
meaningful if slots is set higher than nmemslots. But please Marcelo
double check, thanks!
Signed-off-by: Andrea Arcangeli <andrea@qumranet.com>
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f7726a0..cf04489 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3999,16 +3999,23 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
*/
if (!user_alloc) {
if (npages && !old.rmap) {
+ unsigned long userspace_addr;
+
down_write(¤t->mm->mmap_sem);
- memslot->userspace_addr = do_mmap(NULL, 0,
- npages * PAGE_SIZE,
- PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_ANONYMOUS,
- 0);
+ userspace_addr = do_mmap(NULL, 0,
+ npages * PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS,
+ 0);
up_write(¤t->mm->mmap_sem);
- if (IS_ERR((void *)memslot->userspace_addr))
- return PTR_ERR((void *)memslot->userspace_addr);
+ if (IS_ERR((void *)userspace_addr))
+ return PTR_ERR((void *)userspace_addr);
+
+ /* set userspace_addr atomically for kvm_hva_to_rmapp */
+ spin_lock(&kvm->mmu_lock);
+ memslot->userspace_addr = userspace_addr;
+ spin_unlock(&kvm->mmu_lock);
} else {
if (!old.user_alloc && old.rmap) {
int ret;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 904d7b7..132a26c 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -375,7 +375,15 @@ int __kvm_set_memory_region(struct kvm *kvm,
memset(new.rmap, 0, npages * sizeof(*new.rmap));
new.user_alloc = user_alloc;
- new.userspace_addr = mem->userspace_addr;
+ /*
+ * hva_to_rmmap() serialzies with the mmu_lock and to be
+ * safe it has to ignore memslots with !user_alloc &&
+ * !userspace_addr.
+ */
+ if (user_alloc)
+ new.userspace_addr = mem->userspace_addr;
+ else
+ new.userspace_addr = 0;
}
if (npages && !new.lpage_info) {
int largepages = npages / KVM_PAGES_PER_HPAGE;
@@ -408,17 +416,21 @@ int __kvm_set_memory_region(struct kvm *kvm,
}
#endif /* not defined CONFIG_S390 */
- if (mem->slot >= kvm->nmemslots)
- kvm->nmemslots = mem->slot + 1;
-
if (!npages)
kvm_arch_flush_shadow(kvm);
+ spin_lock(&kvm->mmu_lock);
+ if (mem->slot >= kvm->nmemslots)
+ kvm->nmemslots = mem->slot + 1;
+
*memslot = new;
+ spin_unlock(&kvm->mmu_lock);
r = kvm_arch_set_memory_region(kvm, mem, old, user_alloc);
if (r) {
+ spin_lock(&kvm->mmu_lock);
*memslot = old;
+ spin_unlock(&kvm->mmu_lock);
goto out_free;
}
next prev parent reply other threads:[~2008-07-25 14:32 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-25 14:24 [PATCH 1/6] kvm.git mmu notifier patch Andrea Arcangeli
2008-07-25 14:26 ` [PATCH 2/6] kvm.git allow reading aliases with mmu_lock Andrea Arcangeli
2008-07-25 14:32 ` Andrea Arcangeli [this message]
2008-07-25 14:38 ` [PATCH 4/6] kvm-userland.git mmu notifier compat Andrea Arcangeli
2008-07-25 14:40 ` [PATCH 5/6] kvm.git handle reserved pages as mmio Andrea Arcangeli
2008-07-25 14:44 ` [PATCH 6/6] kvm.git allow reserved pages to be used as guest phys ram Andrea Arcangeli
2008-07-29 12:49 ` [PATCH 4/6] kvm-userland.git mmu notifier compat Avi Kivity
2008-07-29 13:03 ` Andrea Arcangeli
2008-07-29 13:30 ` Avi Kivity
2008-07-29 13:37 ` Andrea Arcangeli
2008-07-28 21:51 ` [PATCH 3/6] kvm.git allow browsing memslots with mmu_lock Marcelo Tosatti
2008-07-28 22:06 ` Andrea Arcangeli
2008-07-28 21:43 ` [PATCH 2/6] kvm.git allow reading aliases " Marcelo Tosatti
2008-07-28 21:11 ` [PATCH 1/6] kvm.git mmu notifier patch Marcelo Tosatti
2008-07-28 21:15 ` Marcelo Tosatti
2008-07-29 9:31 ` 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=20080725143203.GC8217@duo.random \
--to=andrea@qumranet.com \
--cc=avi@qumranet.com \
--cc=kvm@vger.kernel.org \
--cc=marcelo.tosatti@cyclades.com.br \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox